|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_000 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_001 | |||
|---|---|---|---|---|
|
126 lines 5326 bytes Last modified : Mon May 14 23:47:19 2012 |
134 lines 5544 bytes Last modified : Mon May 14 23:47:19 2012 |
|||
| 1 | //Time : 2012-04-12 06:34:46.721 | 1 | //Time : 2012-04-12 06:35:05.964 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | package energy.analysis; | 3 | /*AST Changes : | |
| 4 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 5 | INSERT ExpressionStmt = 1 | |||
| 6 | changes = 1 | |||
| 7 | changes to method processResults = 1 | |||
| 8 | inserts = 1 | |||
| 9 | public method declarations = 1 | |||
| 10 | */package energy.analysis; | |||
| 4 | import java.util.EnumMap; | 11 | import java.util.EnumMap; | |
| 5 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 7 | import java.util.Map; | 14 | import java.util.Map; | |
| 8 | import java.util.Map.Entry; | 15 | import java.util.Map.Entry; | |
| 9 | import java.util.Set; | 16 | import java.util.Set; | |
| 10 | import com.ibm.wala.types.FieldReference; | 17 | import com.ibm.wala.types.FieldReference; | |
| 11 | import com.ibm.wala.util.collections.Pair; | 18 | import com.ibm.wala.util.collections.Pair; | |
| 12 | import energy.components.Component; | 19 | import energy.components.Component; | |
| 13 | import energy.interproc.CompoundLockState; | 20 | import energy.interproc.CompoundLockState; | |
| 14 | import energy.interproc.SingleLockState; | 21 | import energy.interproc.SingleLockState; | |
| 15 | import energy.util.E; | 22 | import energy.util.E; | |
| 16 | public class AnalysisResults { | 23 | public class AnalysisResults { | |
| 17 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 24 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 18 | public class ComponentResult { | 25 | public class ComponentResult { | |
| 19 | HashMap<String,CompoundLockState> callBackExitStates; | 26 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 20 | public ComponentResult(){ | 27 | public ComponentResult(){ | |
| 21 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 28 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 22 | } | 29 | } | |
| 23 | } | 30 | } | |
| 24 | /** | 31 | /** | |
| 25 | * The constructor | 32 | * The constructor | |
| 26 | */ | 33 | */ | |
| 27 | AnalysisResults(){ | 34 | AnalysisResults(){ | |
| 28 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 35 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 29 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 36 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 30 | } | 37 | } | |
| 31 | int threadCount=0; | 38 | int threadCount=0; | |
| 32 | int activityCount=0; | 39 | int activityCount=0; | |
| 33 | int lockThreads=0; | 40 | int lockThreads=0; | |
| 34 | int nolockThreads=0; | 41 | int nolockThreads=0; | |
| 35 | int unlockThreads=0; | 42 | int unlockThreads=0; | |
| 36 | int lockunlockThreads=0; | 43 | int lockunlockThreads=0; | |
| 37 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 44 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 38 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 45 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 39 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 46 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 40 | resultStuff.add(Pair.make(component,map)); | 47 | resultStuff.add(Pair.make(component,map)); | |
| 41 | StringBuffer sb=new StringBuffer(); | 48 | StringBuffer sb=new StringBuffer(); | |
| 42 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 49 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 43 | if (e.getValue().size() > 0) { | 50 | if (e.getValue().size() > 0) { | |
| 44 | sb.append(e.getKey() + "\n"); | 51 | sb.append(e.getKey() + "\n"); | |
| 45 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 52 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 46 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 53 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 47 | } | 54 | } | |
| 48 | } | 55 | } | |
| 49 | } | 56 | } | |
| 50 | if (sb.length() > 0) { | 57 | if (sb.length() > 0) { | |
| 51 | E.log(1,component.toString() + "\n" + sb.toString()); | 58 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 52 | } | 59 | } | |
| 53 | } | 60 | } | |
| 54 | private LockUsage getLockUsage( SingleLockState runState){ | 61 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 55 | if (runState != null) { | 62 | if (runState != null) { | |
| 56 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 63 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 57 | return LockUsage.LOCKING; | 64 | return LockUsage.LOCKING; | |
| 58 | } | 65 | } | |
| 59 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 66 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 60 | return LockUsage.EMPTY; | 67 | return LockUsage.EMPTY; | |
| 61 | } | 68 | } | |
| 62 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 69 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 63 | return LockUsage.FULL_UNLOCKING; | 70 | return LockUsage.FULL_UNLOCKING; | |
| 64 | } | 71 | } | |
| 65 | else if (runState.isMaybeReleased()) { | 72 | else if (runState.isMaybeReleased()) { | |
| 66 | return LockUsage.UNLOCKING; | 73 | return LockUsage.UNLOCKING; | |
| 67 | } | 74 | } | |
| 68 | else { | 75 | else { | |
| 69 | return LockUsage.UNKNOWN_STATE; | 76 | return LockUsage.UNKNOWN_STATE; | |
| 70 | } | 77 | } | |
| 71 | } | 78 | } | |
| 72 | else { | 79 | else { | |
| 73 | return LockUsage.EMPTY; | 80 | return LockUsage.EMPTY; | |
| 74 | } | 81 | } | |
| 75 | } | 82 | } | |
| 76 | public void processResults(){ | 83 | public void processResults(){ | |
| 84 | System.out.pr=$missing$; | |||
| 77 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 85 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 78 | Component component=pair.fst; | 86 | Component component=pair.fst; | |
| 79 | String componentName=component.getComponentName(); | 87 | String componentName=component.getComponentName(); | |
| 80 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 88 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 81 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 89 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 82 | String callBackName=e.getKey(); | 90 | String callBackName=e.getKey(); | |
| 83 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 91 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 84 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 92 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 85 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 93 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 86 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 94 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 87 | FieldReference field=fs.getKey(); | 95 | FieldReference field=fs.getKey(); | |
| 88 | Set<SingleLockState> sls=fs.getValue(); | 96 | Set<SingleLockState> sls=fs.getValue(); | |
| 89 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 97 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 90 | LockUsage lockUsage=getLockUsage(sl); | 98 | LockUsage lockUsage=getLockUsage(sl); | |
| 91 | lockUsages.put(field,lockUsage); | 99 | lockUsages.put(field,lockUsage); | |
| 92 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 100 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 93 | if (lockUsage != LockUsage.EMPTY) { | 101 | if (lockUsage != LockUsage.EMPTY) { | |
| 94 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 102 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 95 | } | 103 | } | |
| 96 | updateEnumMap(enumMap,lockUsage); | 104 | updateEnumMap(enumMap,lockUsage); | |
| 97 | } | 105 | } | |
| 98 | } | 106 | } | |
| 99 | } | 107 | } | |
| 100 | } | 108 | } | |
| 101 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 109 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 102 | if (enumMap == null) { | 110 | if (enumMap == null) { | |
| 103 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 111 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 104 | } | 112 | } | |
| 105 | Integer count=enumMap.get(lockUsage); | 113 | Integer count=enumMap.get(lockUsage); | |
| 106 | if (count == null) { | 114 | if (count == null) { | |
| 107 | count=new Integer(1); | 115 | count=new Integer(1); | |
| 108 | enumMap.put(lockUsage,count); | 116 | enumMap.put(lockUsage,count); | |
| 109 | } | 117 | } | |
| 110 | else { | 118 | else { | |
| 111 | enumMap.put(lockUsage,count + 1); | 119 | enumMap.put(lockUsage,count + 1); | |
| 112 | } | 120 | } | |
| 113 | } | 121 | } | |
| 114 | public void outputFinalResults(){ | 122 | public void outputFinalResults(){ | |
| 115 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 123 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 116 | Pair<String,String> key=e.getKey(); | 124 | Pair<String,String> key=e.getKey(); | |
| 117 | E.log(1,key.toString()); | 125 | E.log(1,key.toString()); | |
| 118 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 126 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 119 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 127 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 120 | LockUsage usage=u.getKey(); | 128 | LockUsage usage=u.getKey(); | |
| 121 | Integer count=u.getValue(); | 129 | Integer count=u.getValue(); | |
| 122 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 130 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 123 | } | 131 | } | |
| 124 | } | 132 | } | |
| 125 | } | 133 | } | |
| 126 | } | 134 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_001 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_002 | |||
|---|---|---|---|---|
|
134 lines 5544 bytes Last modified : Mon May 14 23:47:19 2012 |
133 lines 5548 bytes Last modified : Mon May 14 23:47:19 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:05.964 | 1 | //Time : 2012-04-12 06:35:08.289 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 4 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 5 | INSERT ExpressionStmt = 1 | 6 | changes = 2 | |
| 6 | changes = 1 | |||
| 7 | changes to method processResults = 1 | 7 | changes to method processResults = 1 | |
| 8 | inserts = 1 | |||
| 9 | public method declarations = 1 | 8 | public method declarations = 1 | |
| 10 | */package energy.analysis; | 9 | */package energy.analysis; | |
| 11 | import java.util.EnumMap; | 10 | import java.util.EnumMap; | |
| 12 | import java.util.HashMap; | 11 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 12 | import java.util.HashSet; | |
| 14 | import java.util.Map; | 13 | import java.util.Map; | |
| 15 | import java.util.Map.Entry; | 14 | import java.util.Map.Entry; | |
| 16 | import java.util.Set; | 15 | import java.util.Set; | |
| 17 | import com.ibm.wala.types.FieldReference; | 16 | import com.ibm.wala.types.FieldReference; | |
| 18 | import com.ibm.wala.util.collections.Pair; | 17 | import com.ibm.wala.util.collections.Pair; | |
| 19 | import energy.components.Component; | 18 | import energy.components.Component; | |
| 20 | import energy.interproc.CompoundLockState; | 19 | import energy.interproc.CompoundLockState; | |
| 21 | import energy.interproc.SingleLockState; | 20 | import energy.interproc.SingleLockState; | |
| 22 | import energy.util.E; | 21 | import energy.util.E; | |
| 23 | public class AnalysisResults { | 22 | public class AnalysisResults { | |
| 24 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 23 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 25 | public class ComponentResult { | 24 | public class ComponentResult { | |
| 26 | HashMap<String,CompoundLockState> callBackExitStates; | 25 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 27 | public ComponentResult(){ | 26 | public ComponentResult(){ | |
| 28 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 27 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 29 | } | 28 | } | |
| 30 | } | 29 | } | |
| 31 | /** | 30 | /** | |
| 32 | * The constructor | 31 | * The constructor | |
| 33 | */ | 32 | */ | |
| 34 | AnalysisResults(){ | 33 | AnalysisResults(){ | |
| 35 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 34 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 36 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 35 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 37 | } | 36 | } | |
| 38 | int threadCount=0; | 37 | int threadCount=0; | |
| 39 | int activityCount=0; | 38 | int activityCount=0; | |
| 40 | int lockThreads=0; | 39 | int lockThreads=0; | |
| 41 | int nolockThreads=0; | 40 | int nolockThreads=0; | |
| 42 | int unlockThreads=0; | 41 | int unlockThreads=0; | |
| 43 | int lockunlockThreads=0; | 42 | int lockunlockThreads=0; | |
| 44 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 43 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 45 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 44 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 46 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 45 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 47 | resultStuff.add(Pair.make(component,map)); | 46 | resultStuff.add(Pair.make(component,map)); | |
| 48 | StringBuffer sb=new StringBuffer(); | 47 | StringBuffer sb=new StringBuffer(); | |
| 49 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 48 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 50 | if (e.getValue().size() > 0) { | 49 | if (e.getValue().size() > 0) { | |
| 51 | sb.append(e.getKey() + "\n"); | 50 | sb.append(e.getKey() + "\n"); | |
| 52 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 51 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 53 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 52 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 54 | } | 53 | } | |
| 55 | } | 54 | } | |
| 56 | } | 55 | } | |
| 57 | if (sb.length() > 0) { | 56 | if (sb.length() > 0) { | |
| 58 | E.log(1,component.toString() + "\n" + sb.toString()); | 57 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 59 | } | 58 | } | |
| 60 | } | 59 | } | |
| 61 | private LockUsage getLockUsage( SingleLockState runState){ | 60 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 62 | if (runState != null) { | 61 | if (runState != null) { | |
| 63 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 62 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 64 | return LockUsage.LOCKING; | 63 | return LockUsage.LOCKING; | |
| 65 | } | 64 | } | |
| 66 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 65 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 67 | return LockUsage.EMPTY; | 66 | return LockUsage.EMPTY; | |
| 68 | } | 67 | } | |
| 69 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 68 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 70 | return LockUsage.FULL_UNLOCKING; | 69 | return LockUsage.FULL_UNLOCKING; | |
| 71 | } | 70 | } | |
| 72 | else if (runState.isMaybeReleased()) { | 71 | else if (runState.isMaybeReleased()) { | |
| 73 | return LockUsage.UNLOCKING; | 72 | return LockUsage.UNLOCKING; | |
| 74 | } | 73 | } | |
| 75 | else { | 74 | else { | |
| 76 | return LockUsage.UNKNOWN_STATE; | 75 | return LockUsage.UNKNOWN_STATE; | |
| 77 | } | 76 | } | |
| 78 | } | 77 | } | |
| 79 | else { | 78 | else { | |
| 80 | return LockUsage.EMPTY; | 79 | return LockUsage.EMPTY; | |
| 81 | } | 80 | } | |
| 82 | } | 81 | } | |
| 83 | public void processResults(){ | 82 | public void processResults(){ | |
| 84 | System.out.pr=$missing$; | 83 | System.out.println(); | |
| 85 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 84 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 86 | Component component=pair.fst; | 85 | Component component=pair.fst; | |
| 87 | String componentName=component.getComponentName(); | 86 | String componentName=component.getComponentName(); | |
| 88 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 87 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 89 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 88 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 90 | String callBackName=e.getKey(); | 89 | String callBackName=e.getKey(); | |
| 91 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 90 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 92 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 91 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 93 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 92 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 94 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 93 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 95 | FieldReference field=fs.getKey(); | 94 | FieldReference field=fs.getKey(); | |
| 96 | Set<SingleLockState> sls=fs.getValue(); | 95 | Set<SingleLockState> sls=fs.getValue(); | |
| 97 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 96 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 98 | LockUsage lockUsage=getLockUsage(sl); | 97 | LockUsage lockUsage=getLockUsage(sl); | |
| 99 | lockUsages.put(field,lockUsage); | 98 | lockUsages.put(field,lockUsage); | |
| 100 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 99 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 101 | if (lockUsage != LockUsage.EMPTY) { | 100 | if (lockUsage != LockUsage.EMPTY) { | |
| 102 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 101 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 103 | } | 102 | } | |
| 104 | updateEnumMap(enumMap,lockUsage); | 103 | updateEnumMap(enumMap,lockUsage); | |
| 105 | } | 104 | } | |
| 106 | } | 105 | } | |
| 107 | } | 106 | } | |
| 108 | } | 107 | } | |
| 109 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 108 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 110 | if (enumMap == null) { | 109 | if (enumMap == null) { | |
| 111 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 110 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 112 | } | 111 | } | |
| 113 | Integer count=enumMap.get(lockUsage); | 112 | Integer count=enumMap.get(lockUsage); | |
| 114 | if (count == null) { | 113 | if (count == null) { | |
| 115 | count=new Integer(1); | 114 | count=new Integer(1); | |
| 116 | enumMap.put(lockUsage,count); | 115 | enumMap.put(lockUsage,count); | |
| 117 | } | 116 | } | |
| 118 | else { | 117 | else { | |
| 119 | enumMap.put(lockUsage,count + 1); | 118 | enumMap.put(lockUsage,count + 1); | |
| 120 | } | 119 | } | |
| 121 | } | 120 | } | |
| 122 | public void outputFinalResults(){ | 121 | public void outputFinalResults(){ | |
| 123 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 122 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 124 | Pair<String,String> key=e.getKey(); | 123 | Pair<String,String> key=e.getKey(); | |
| 125 | E.log(1,key.toString()); | 124 | E.log(1,key.toString()); | |
| 126 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 125 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 127 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 126 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 128 | LockUsage usage=u.getKey(); | 127 | LockUsage usage=u.getKey(); | |
| 129 | Integer count=u.getValue(); | 128 | Integer count=u.getValue(); | |
| 130 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 129 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 131 | } | 130 | } | |
| 132 | } | 131 | } | |
| 133 | } | 132 | } | |
| 134 | } | 133 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_002 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_003 | |||
|---|---|---|---|---|
|
133 lines 5548 bytes Last modified : Mon May 14 23:47:19 2012 |
133 lines 5550 bytes Last modified : Mon May 14 23:47:19 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:08.289 | 1 | //Time : 2012-04-12 06:35:09.539 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 4 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | changes = 2 | 6 | changes = 2 | |
| 7 | changes to method processResults = 1 | 7 | changes to method processResults = 1 | |
| 8 | public method declarations = 1 | 8 | public method declarations = 1 | |
| 9 | */package energy.analysis; | 9 | */package energy.analysis; | |
| 10 | import java.util.EnumMap; | 10 | import java.util.EnumMap; | |
| 11 | import java.util.HashMap; | 11 | import java.util.HashMap; | |
| 12 | import java.util.HashSet; | 12 | import java.util.HashSet; | |
| 13 | import java.util.Map; | 13 | import java.util.Map; | |
| 14 | import java.util.Map.Entry; | 14 | import java.util.Map.Entry; | |
| 15 | import java.util.Set; | 15 | import java.util.Set; | |
| 16 | import com.ibm.wala.types.FieldReference; | 16 | import com.ibm.wala.types.FieldReference; | |
| 17 | import com.ibm.wala.util.collections.Pair; | 17 | import com.ibm.wala.util.collections.Pair; | |
| 18 | import energy.components.Component; | 18 | import energy.components.Component; | |
| 19 | import energy.interproc.CompoundLockState; | 19 | import energy.interproc.CompoundLockState; | |
| 20 | import energy.interproc.SingleLockState; | 20 | import energy.interproc.SingleLockState; | |
| 21 | import energy.util.E; | 21 | import energy.util.E; | |
| 22 | public class AnalysisResults { | 22 | public class AnalysisResults { | |
| 23 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 23 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 24 | public class ComponentResult { | 24 | public class ComponentResult { | |
| 25 | HashMap<String,CompoundLockState> callBackExitStates; | 25 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 26 | public ComponentResult(){ | 26 | public ComponentResult(){ | |
| 27 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 27 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 28 | } | 28 | } | |
| 29 | } | 29 | } | |
| 30 | /** | 30 | /** | |
| 31 | * The constructor | 31 | * The constructor | |
| 32 | */ | 32 | */ | |
| 33 | AnalysisResults(){ | 33 | AnalysisResults(){ | |
| 34 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 34 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 35 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 35 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 36 | } | 36 | } | |
| 37 | int threadCount=0; | 37 | int threadCount=0; | |
| 38 | int activityCount=0; | 38 | int activityCount=0; | |
| 39 | int lockThreads=0; | 39 | int lockThreads=0; | |
| 40 | int nolockThreads=0; | 40 | int nolockThreads=0; | |
| 41 | int unlockThreads=0; | 41 | int unlockThreads=0; | |
| 42 | int lockunlockThreads=0; | 42 | int lockunlockThreads=0; | |
| 43 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 43 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 44 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 44 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 45 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 45 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 46 | resultStuff.add(Pair.make(component,map)); | 46 | resultStuff.add(Pair.make(component,map)); | |
| 47 | StringBuffer sb=new StringBuffer(); | 47 | StringBuffer sb=new StringBuffer(); | |
| 48 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 48 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 49 | if (e.getValue().size() > 0) { | 49 | if (e.getValue().size() > 0) { | |
| 50 | sb.append(e.getKey() + "\n"); | 50 | sb.append(e.getKey() + "\n"); | |
| 51 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 51 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 52 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 52 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | } | 55 | } | |
| 56 | if (sb.length() > 0) { | 56 | if (sb.length() > 0) { | |
| 57 | E.log(1,component.toString() + "\n" + sb.toString()); | 57 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 58 | } | 58 | } | |
| 59 | } | 59 | } | |
| 60 | private LockUsage getLockUsage( SingleLockState runState){ | 60 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 61 | if (runState != null) { | 61 | if (runState != null) { | |
| 62 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 62 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 63 | return LockUsage.LOCKING; | 63 | return LockUsage.LOCKING; | |
| 64 | } | 64 | } | |
| 65 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 65 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 66 | return LockUsage.EMPTY; | 66 | return LockUsage.EMPTY; | |
| 67 | } | 67 | } | |
| 68 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 68 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 69 | return LockUsage.FULL_UNLOCKING; | 69 | return LockUsage.FULL_UNLOCKING; | |
| 70 | } | 70 | } | |
| 71 | else if (runState.isMaybeReleased()) { | 71 | else if (runState.isMaybeReleased()) { | |
| 72 | return LockUsage.UNLOCKING; | 72 | return LockUsage.UNLOCKING; | |
| 73 | } | 73 | } | |
| 74 | else { | 74 | else { | |
| 75 | return LockUsage.UNKNOWN_STATE; | 75 | return LockUsage.UNKNOWN_STATE; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | else { | 78 | else { | |
| 79 | return LockUsage.EMPTY; | 79 | return LockUsage.EMPTY; | |
| 80 | } | 80 | } | |
| 81 | } | 81 | } | |
| 82 | public void processResults(){ | 82 | public void processResults(){ | |
| 83 | System.out.println(); | 83 | System.out.println(""); | |
| 84 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 84 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 85 | Component component=pair.fst; | 85 | Component component=pair.fst; | |
| 86 | String componentName=component.getComponentName(); | 86 | String componentName=component.getComponentName(); | |
| 87 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 87 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 88 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 88 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 89 | String callBackName=e.getKey(); | 89 | String callBackName=e.getKey(); | |
| 90 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 90 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 91 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 91 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 92 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 92 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 93 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 93 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 94 | FieldReference field=fs.getKey(); | 94 | FieldReference field=fs.getKey(); | |
| 95 | Set<SingleLockState> sls=fs.getValue(); | 95 | Set<SingleLockState> sls=fs.getValue(); | |
| 96 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 96 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 97 | LockUsage lockUsage=getLockUsage(sl); | 97 | LockUsage lockUsage=getLockUsage(sl); | |
| 98 | lockUsages.put(field,lockUsage); | 98 | lockUsages.put(field,lockUsage); | |
| 99 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 99 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 100 | if (lockUsage != LockUsage.EMPTY) { | 100 | if (lockUsage != LockUsage.EMPTY) { | |
| 101 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 101 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 102 | } | 102 | } | |
| 103 | updateEnumMap(enumMap,lockUsage); | 103 | updateEnumMap(enumMap,lockUsage); | |
| 104 | } | 104 | } | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | } | 107 | } | |
| 108 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 108 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 109 | if (enumMap == null) { | 109 | if (enumMap == null) { | |
| 110 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 110 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 111 | } | 111 | } | |
| 112 | Integer count=enumMap.get(lockUsage); | 112 | Integer count=enumMap.get(lockUsage); | |
| 113 | if (count == null) { | 113 | if (count == null) { | |
| 114 | count=new Integer(1); | 114 | count=new Integer(1); | |
| 115 | enumMap.put(lockUsage,count); | 115 | enumMap.put(lockUsage,count); | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | enumMap.put(lockUsage,count + 1); | 118 | enumMap.put(lockUsage,count + 1); | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public void outputFinalResults(){ | 121 | public void outputFinalResults(){ | |
| 122 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 122 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 123 | Pair<String,String> key=e.getKey(); | 123 | Pair<String,String> key=e.getKey(); | |
| 124 | E.log(1,key.toString()); | 124 | E.log(1,key.toString()); | |
| 125 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 125 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 126 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 126 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 127 | LockUsage usage=u.getKey(); | 127 | LockUsage usage=u.getKey(); | |
| 128 | Integer count=u.getValue(); | 128 | Integer count=u.getValue(); | |
| 129 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 129 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 130 | } | 130 | } | |
| 131 | } | 131 | } | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_003 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_004 | |||
|---|---|---|---|---|
|
133 lines 5550 bytes Last modified : Mon May 14 23:47:19 2012 |
133 lines 5552 bytes Last modified : Mon May 14 23:47:19 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:09.539 | 1 | //Time : 2012-04-12 06:35:10.781 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 4 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | changes = 2 | 6 | changes = 2 | |
| 7 | changes to method processResults = 1 | 7 | changes to method processResults = 1 | |
| 8 | public method declarations = 1 | 8 | public method declarations = 1 | |
| 9 | */package energy.analysis; | 9 | */package energy.analysis; | |
| 10 | import java.util.EnumMap; | 10 | import java.util.EnumMap; | |
| 11 | import java.util.HashMap; | 11 | import java.util.HashMap; | |
| 12 | import java.util.HashSet; | 12 | import java.util.HashSet; | |
| 13 | import java.util.Map; | 13 | import java.util.Map; | |
| 14 | import java.util.Map.Entry; | 14 | import java.util.Map.Entry; | |
| 15 | import java.util.Set; | 15 | import java.util.Set; | |
| 16 | import com.ibm.wala.types.FieldReference; | 16 | import com.ibm.wala.types.FieldReference; | |
| 17 | import com.ibm.wala.util.collections.Pair; | 17 | import com.ibm.wala.util.collections.Pair; | |
| 18 | import energy.components.Component; | 18 | import energy.components.Component; | |
| 19 | import energy.interproc.CompoundLockState; | 19 | import energy.interproc.CompoundLockState; | |
| 20 | import energy.interproc.SingleLockState; | 20 | import energy.interproc.SingleLockState; | |
| 21 | import energy.util.E; | 21 | import energy.util.E; | |
| 22 | public class AnalysisResults { | 22 | public class AnalysisResults { | |
| 23 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | 23 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |
| 24 | public class ComponentResult { | 24 | public class ComponentResult { | |
| 25 | HashMap<String,CompoundLockState> callBackExitStates; | 25 | HashMap<String,CompoundLockState> callBackExitStates; | |
| 26 | public ComponentResult(){ | 26 | public ComponentResult(){ | |
| 27 | callBackExitStates=new HashMap<String,CompoundLockState>(); | 27 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |
| 28 | } | 28 | } | |
| 29 | } | 29 | } | |
| 30 | /** | 30 | /** | |
| 31 | * The constructor | 31 | * The constructor | |
| 32 | */ | 32 | */ | |
| 33 | AnalysisResults(){ | 33 | AnalysisResults(){ | |
| 34 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 34 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | |
| 35 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 35 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | |
| 36 | } | 36 | } | |
| 37 | int threadCount=0; | 37 | int threadCount=0; | |
| 38 | int activityCount=0; | 38 | int activityCount=0; | |
| 39 | int lockThreads=0; | 39 | int lockThreads=0; | |
| 40 | int nolockThreads=0; | 40 | int nolockThreads=0; | |
| 41 | int unlockThreads=0; | 41 | int unlockThreads=0; | |
| 42 | int lockunlockThreads=0; | 42 | int lockunlockThreads=0; | |
| 43 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 43 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 44 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 44 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | |
| 45 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 45 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | |
| 46 | resultStuff.add(Pair.make(component,map)); | 46 | resultStuff.add(Pair.make(component,map)); | |
| 47 | StringBuffer sb=new StringBuffer(); | 47 | StringBuffer sb=new StringBuffer(); | |
| 48 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 48 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | |
| 49 | if (e.getValue().size() > 0) { | 49 | if (e.getValue().size() > 0) { | |
| 50 | sb.append(e.getKey() + "\n"); | 50 | sb.append(e.getKey() + "\n"); | |
| 51 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 51 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | |
| 52 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 52 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | |
| 53 | } | 53 | } | |
| 54 | } | 54 | } | |
| 55 | } | 55 | } | |
| 56 | if (sb.length() > 0) { | 56 | if (sb.length() > 0) { | |
| 57 | E.log(1,component.toString() + "\n" + sb.toString()); | 57 | E.log(1,component.toString() + "\n" + sb.toString()); | |
| 58 | } | 58 | } | |
| 59 | } | 59 | } | |
| 60 | private LockUsage getLockUsage( SingleLockState runState){ | 60 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 61 | if (runState != null) { | 61 | if (runState != null) { | |
| 62 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 62 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 63 | return LockUsage.LOCKING; | 63 | return LockUsage.LOCKING; | |
| 64 | } | 64 | } | |
| 65 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 65 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 66 | return LockUsage.EMPTY; | 66 | return LockUsage.EMPTY; | |
| 67 | } | 67 | } | |
| 68 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 68 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 69 | return LockUsage.FULL_UNLOCKING; | 69 | return LockUsage.FULL_UNLOCKING; | |
| 70 | } | 70 | } | |
| 71 | else if (runState.isMaybeReleased()) { | 71 | else if (runState.isMaybeReleased()) { | |
| 72 | return LockUsage.UNLOCKING; | 72 | return LockUsage.UNLOCKING; | |
| 73 | } | 73 | } | |
| 74 | else { | 74 | else { | |
| 75 | return LockUsage.UNKNOWN_STATE; | 75 | return LockUsage.UNKNOWN_STATE; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | else { | 78 | else { | |
| 79 | return LockUsage.EMPTY; | 79 | return LockUsage.EMPTY; | |
| 80 | } | 80 | } | |
| 81 | } | 81 | } | |
| 82 | public void processResults(){ | 82 | public void processResults(){ | |
| 83 | System.out.println(""); | 83 | System.out.println("\n"); | |
| 84 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 84 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | |
| 85 | Component component=pair.fst; | 85 | Component component=pair.fst; | |
| 86 | String componentName=component.getComponentName(); | 86 | String componentName=component.getComponentName(); | |
| 87 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 87 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | |
| 88 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 88 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | |
| 89 | String callBackName=e.getKey(); | 89 | String callBackName=e.getKey(); | |
| 90 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 90 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | |
| 91 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 91 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | |
| 92 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 92 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | |
| 93 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 93 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | |
| 94 | FieldReference field=fs.getKey(); | 94 | FieldReference field=fs.getKey(); | |
| 95 | Set<SingleLockState> sls=fs.getValue(); | 95 | Set<SingleLockState> sls=fs.getValue(); | |
| 96 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 96 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 97 | LockUsage lockUsage=getLockUsage(sl); | 97 | LockUsage lockUsage=getLockUsage(sl); | |
| 98 | lockUsages.put(field,lockUsage); | 98 | lockUsages.put(field,lockUsage); | |
| 99 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | 99 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |
| 100 | if (lockUsage != LockUsage.EMPTY) { | 100 | if (lockUsage != LockUsage.EMPTY) { | |
| 101 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 101 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | |
| 102 | } | 102 | } | |
| 103 | updateEnumMap(enumMap,lockUsage); | 103 | updateEnumMap(enumMap,lockUsage); | |
| 104 | } | 104 | } | |
| 105 | } | 105 | } | |
| 106 | } | 106 | } | |
| 107 | } | 107 | } | |
| 108 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 108 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | |
| 109 | if (enumMap == null) { | 109 | if (enumMap == null) { | |
| 110 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 110 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | |
| 111 | } | 111 | } | |
| 112 | Integer count=enumMap.get(lockUsage); | 112 | Integer count=enumMap.get(lockUsage); | |
| 113 | if (count == null) { | 113 | if (count == null) { | |
| 114 | count=new Integer(1); | 114 | count=new Integer(1); | |
| 115 | enumMap.put(lockUsage,count); | 115 | enumMap.put(lockUsage,count); | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | enumMap.put(lockUsage,count + 1); | 118 | enumMap.put(lockUsage,count + 1); | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public void outputFinalResults(){ | 121 | public void outputFinalResults(){ | |
| 122 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 122 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | |
| 123 | Pair<String,String> key=e.getKey(); | 123 | Pair<String,String> key=e.getKey(); | |
| 124 | E.log(1,key.toString()); | 124 | E.log(1,key.toString()); | |
| 125 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 125 | EnumMap<LockUsage,Integer> usages=e.getValue(); | |
| 126 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 126 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | |
| 127 | LockUsage usage=u.getKey(); | 127 | LockUsage usage=u.getKey(); | |
| 128 | Integer count=u.getValue(); | 128 | Integer count=u.getValue(); | |
| 129 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 129 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | |
| 130 | } | 130 | } | |
| 131 | } | 131 | } | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_004 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_005 | |||
|---|---|---|---|---|
|
133 lines 5552 bytes Last modified : Mon May 14 23:47:19 2012 |
305 lines 11787 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-12 06:35:10.781 | 1 | //Time : 2012-04-24 18:21:38.377 | |
| 2 | //Files Open : /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java /pvekris/src/main/java/energy/interproc/CtxSensLocking.java /pvekris/src/main/java/energy/analysis/WakeLockManager.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/SpecialConditions.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | package energy.analysis; | |
| 4 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 4 | import java.util.ArrayList; | |
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 6 | changes = 2 | |||
| 7 | changes to method processResults = 1 | |||
| 8 | public method declarations = 1 | |||
| 9 | */package energy.analysis; | |||
| 10 | import java.util.EnumMap; | |||
| 11 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 12 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | |||
| 13 | import java.util.Map; | 8 | import java.util.Map; | |
| 14 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 15 | import java.util.Set; | 10 | import java.util.Set; | |
| 16 | import com.ibm.wala.types.FieldReference; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 17 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |||
| 18 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | |||
| 19 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 20 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 21 | import energy.util.E; | 18 | import energy.util.E; | |
| 22 | public class AnalysisResults { | 19 | public class AnalysisResults { | |
| 23 | private HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>> resultStuff=null; | |||
| 24 | public class ComponentResult { | |||
| 25 | HashMap<String,CompoundLockState> callBackExitStates; | |||
| 26 | public ComponentResult(){ | |||
| 27 | callBackExitStates=new HashMap<String,CompoundLockState>(); | |||
| 28 | } | |||
| 29 | } | |||
| 30 | /** | 20 | /** | |
| 31 | * The constructor | 21 | * Main structures that hold the analysis results for every component | |
| 32 | */ | 22 | */ | |
| 33 | AnalysisResults(){ | 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 34 | resultStuff=new HashSet<Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>>>(); | 24 | public class ComponentSummary { | |
| 35 | callBackResultMap=new HashMap<Pair<String,String>,EnumMap<LockUsage,Integer>>(); | 25 | private Component component; | |
| 36 | } | 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 37 | int threadCount=0; | 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 38 | int activityCount=0; | 28 | public ComponentSummary( Component c){ | |
| 39 | int lockThreads=0; | 29 | this.component=c; | |
| 40 | int nolockThreads=0; | 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 41 | int unlockThreads=0; | 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 42 | int lockunlockThreads=0; | 32 | } | |
| 43 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 44 | private Map<Pair<String,String>,EnumMap<LockUsage,Integer>> callBackResultMap; | 34 | return allExitStates; | |
| 45 | public void registerExitLockState( Component component, Map<String,Map<FieldReference,Set<SingleLockState>>> map){ | 35 | } | |
| 46 | resultStuff.add(Pair.make(component,map)); | 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 47 | StringBuffer sb=new StringBuffer(); | 37 | allExitStates.put(n,st); | |
| 48 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : map.entrySet()) { | 38 | } | |
| 49 | if (e.getValue().size() > 0) { | 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 50 | sb.append(e.getKey() + "\n"); | 40 | callBackExitStates.put(cb,st); | |
| 51 | for ( Entry<FieldReference,Set<SingleLockState>> entry : e.getValue().entrySet()) { | 41 | } | |
| 52 | sb.append(entry.getKey() + " -> " + entry.getValue().toString()); | 42 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | |||
| 44 | } | |||
| 45 | public String toString(){ | |||
| 46 | StringBuffer sb=new StringBuffer(); | |||
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |||
| 48 | CGNode next=it.next(); | |||
| 49 | String name=next.getMethod().getName().toString(); | |||
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | |||
| 51 | if (stateForMethod != null) { | |||
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | |||
| 53 | } | |||
| 54 | } | |||
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | |||
| 56 | if (callbacks != null) { | |||
| 57 | if (callbacks.size() > 0) { | |||
| 58 | sb.append("Callbacks:\n"); | |||
| 59 | for ( CallBack cb : callbacks) { | |||
| 60 | String name=cb.getName(); | |||
| 61 | ; | |||
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | |||
| 63 | if (stateForMethod != null) { | |||
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |||
| 65 | } | |||
| 66 | } | |||
| 53 | } | 67 | } | |
| 54 | } | 68 | } | |
| 69 | return null; | |||
| 55 | } | 70 | } | |
| 56 | if (sb.length() > 0) { | 71 | } | |
| 57 | E.log(1,component.toString() + "\n" + sb.toString()); | 72 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |||
| 74 | } | |||
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |||
| 76 | /** | |||
| 77 | * Invoke this after the component has been analyzed | |||
| 78 | * @param component | |||
| 79 | */ | |||
| 80 | public void createComponentSummary( Component component){ | |||
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | |||
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |||
| 83 | CGNode next=it.next(); | |||
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |||
| 85 | if (exitState != null) { | |||
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |||
| 87 | componentSummary.registerNodeState(next,compoundLockState); | |||
| 88 | } | |||
| 58 | } | 89 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | |||
| 59 | } | 91 | } | |
| 60 | private LockUsage getLockUsage( SingleLockState runState){ | 92 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 61 | if (runState != null) { | 93 | if (runState != null) { | |
| 62 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 63 | return LockUsage.LOCKING; | 95 | return LockUsage.LOCKING; | |
| 64 | } | 96 | } | |
| 65 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 66 | return LockUsage.EMPTY; | 98 | return LockUsage.EMPTY; | |
| 67 | } | 99 | } | |
| 68 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 69 | return LockUsage.FULL_UNLOCKING; | 101 | return LockUsage.FULL_UNLOCKING; | |
| 70 | } | 102 | } | |
| 71 | else if (runState.isMaybeReleased()) { | 103 | else if (runState.isMaybeReleased()) { | |
| 72 | return LockUsage.UNLOCKING; | 104 | return LockUsage.UNLOCKING; | |
| 73 | } | 105 | } | |
| 74 | else { | 106 | else { | |
| 75 | return LockUsage.UNKNOWN_STATE; | 107 | return LockUsage.UNKNOWN_STATE; | |
| 76 | } | 108 | } | |
| 77 | } | 109 | } | |
| 78 | else { | 110 | else { | |
| 79 | return LockUsage.EMPTY; | 111 | return LockUsage.EMPTY; | |
| 80 | } | 112 | } | |
| 81 | } | 113 | } | |
| 82 | public void processResults(){ | 114 | public ArrayList<String> processResults(){ | |
| 83 | System.out.println("\n"); | 115 | ArrayList<String> result=null; | |
| 84 | for ( Pair<Component,Map<String,Map<FieldReference,Set<SingleLockState>>>> pair : resultStuff) { | 116 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |||
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |||
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |||
| 85 | Component component=pair.fst; | 120 | Component component=pair.fst; | |
| 86 | String componentName=component.getComponentName(); | 121 | ComponentSummary cSummary=pair.snd; | |
| 87 | Map<String,Map<FieldReference,Set<SingleLockState>>> callBackMap=pair.snd; | 122 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 88 | for ( Entry<String,Map<FieldReference,Set<SingleLockState>>> e : callBackMap.entrySet()) { | 123 | StringBuffer sb=new StringBuffer(); | |
| 89 | String callBackName=e.getKey(); | 124 | boolean printComponent=false; | |
| 90 | Pair<String,String> compAndCB=Pair.make(component.toString(),callBackName); | 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 91 | Pair<String,String> abstCompAndCB=Pair.make(componentName,callBackName); | 126 | CGNode node=e.getKey(); | |
| 92 | HashMap<FieldReference,LockUsage> lockUsages=new HashMap<FieldReference,LockUsage>(); | 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 93 | for ( Entry<FieldReference,Set<SingleLockState>> fs : e.getValue().entrySet()) { | 128 | boolean printMethod=false; | |
| 94 | FieldReference field=fs.getKey(); | 129 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | |||
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |||
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |||
| 133 | WakeLockInstance wli=fs.getKey(); | |||
| 95 | Set<SingleLockState> sls=fs.getValue(); | 134 | Set<SingleLockState> sls=fs.getValue(); | |
| 96 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 97 | LockUsage lockUsage=getLockUsage(sl); | 136 | lockUsage=getLockUsage(sl); | |
| 98 | lockUsages.put(field,lockUsage); | 137 | lockUsages.put(wli,lockUsage); | |
| 99 | EnumMap<LockUsage,Integer> enumMap=callBackResultMap.get(abstCompAndCB); | |||
| 100 | if (lockUsage != LockUsage.EMPTY) { | 138 | if (lockUsage != LockUsage.EMPTY) { | |
| 101 | E.log(1,compAndCB.toString() + " :: " + lockUsage.toString()); | 139 | printMethod=true; | |
| 102 | } | 140 | } | |
| 103 | updateEnumMap(enumMap,lockUsage); | |||
| 104 | } | 141 | } | |
| 142 | if (printMethod) { | |||
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |||
| 144 | printComponent=true; | |||
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |||
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |||
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |||
| 148 | WakeLockInstance key=fs.getKey(); | |||
| 149 | Set<SingleLockState> value=fs.getValue(); | |||
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |||
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |||
| 152 | } | |||
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |||
| 154 | LockUsage lu=getLockUsage(mergedLS); | |||
| 155 | if (component.isCallBack(node)) { | |||
| 156 | if (usageMap.containsKey(lu)) { | |||
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | |||
| 158 | } | |||
| 159 | else { | |||
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |||
| 161 | set.add(Pair.make(component,node)); | |||
| 162 | usageMap.put(lu,set); | |||
| 163 | } | |||
| 164 | policy.addFact(node,mergedLS); | |||
| 165 | } | |||
| 166 | } | |||
| 167 | } | |||
| 168 | } | |||
| 169 | if (printComponent) { | |||
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | |||
| 171 | policy.solveFacts(); | |||
| 172 | componentMap.put(component,policy.getLogger()); | |||
| 105 | } | 173 | } | |
| 106 | } | 174 | } | |
| 175 | System.out.println("==========================================\n"); | |||
| 176 | for ( LockUsage e : usageMap.keySet()) { | |||
| 177 | System.out.println(e.toString()); | |||
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |||
| 179 | System.out.println(" " + s.toString()); | |||
| 180 | } | |||
| 181 | } | |||
| 182 | System.out.println("==========================================\n"); | |||
| 183 | for ( Component e : componentMap.keySet()) { | |||
| 184 | Logger logger=componentMap.get(e); | |||
| 185 | if (!logger.isEmpty()) { | |||
| 186 | System.out.println(e.toString()); | |||
| 187 | System.out.println(logger.toString()); | |||
| 188 | System.out.println("\n"); | |||
| 189 | } | |||
| 190 | result=logger.getStringList(); | |||
| 191 | } | |||
| 192 | return result; | |||
| 107 | } | 193 | } | |
| 108 | private void updateEnumMap( EnumMap<LockUsage,Integer> enumMap, LockUsage lockUsage){ | 194 | public class Logger extends ArrayList<String> { | |
| 109 | if (enumMap == null) { | 195 | private static final long serialVersionUID=4402714524487791090L; | |
| 110 | enumMap=new EnumMap<LockUsage,Integer>(LockUsage.class); | 196 | public void output(){ | |
| 197 | for ( String s : this) { | |||
| 198 | System.out.println(" " + s); | |||
| 199 | } | |||
| 111 | } | 200 | } | |
| 112 | Integer count=enumMap.get(lockUsage); | 201 | public ArrayList<String> getStringList(){ | |
| 113 | if (count == null) { | 202 | return this; | |
| 114 | count=new Integer(1); | |||
| 115 | enumMap.put(lockUsage,count); | |||
| 116 | } | 203 | } | |
| 117 | else { | 204 | public String toString(){ | |
| 118 | enumMap.put(lockUsage,count + 1); | 205 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | |||
| 207 | result.append(s + "\n"); | |||
| 208 | } | |||
| 209 | return result.toString(); | |||
| 119 | } | 210 | } | |
| 120 | } | 211 | } | |
| 121 | public void outputFinalResults(){ | 212 | public class ComponentPolicy { | |
| 122 | for ( Entry<Pair<String,String>,EnumMap<LockUsage,Integer>> e : callBackResultMap.entrySet()) { | 213 | private Component component; | |
| 123 | Pair<String,String> key=e.getKey(); | 214 | public ComponentPolicy( Component component){ | |
| 124 | E.log(1,key.toString()); | 215 | this.component=component; | |
| 125 | EnumMap<LockUsage,Integer> usages=e.getValue(); | 216 | map=new HashMap<String,SingleLockState>(); | |
| 126 | for ( Entry<LockUsage,Integer> u : usages.entrySet()) { | 217 | logger=new Logger(); | |
| 127 | LockUsage usage=u.getKey(); | 218 | } | |
| 128 | Integer count=u.getValue(); | 219 | private HashMap<String,SingleLockState> map; | |
| 129 | E.log(1,"--> " + usage.toString() + " :: "+ count.toString()); | 220 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | |||
| 222 | } | |||
| 223 | private boolean unlocking( SingleLockState state){ | |||
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | |||
| 225 | } | |||
| 226 | private boolean strongUnlocking( SingleLockState state){ | |||
| 227 | if (state != null) { | |||
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |||
| 229 | } | |||
| 230 | return false; | |||
| 231 | } | |||
| 232 | private boolean weakUnlocking( SingleLockState state){ | |||
| 233 | if (state != null) { | |||
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |||
| 235 | } | |||
| 236 | return false; | |||
| 237 | } | |||
| 238 | private boolean locking( SingleLockState onCreateState){ | |||
| 239 | if (onCreateState != null) { | |||
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |||
| 241 | } | |||
| 242 | return false; | |||
| 243 | } | |||
| 244 | private Logger logger; | |||
| 245 | private void logNote( String s){ | |||
| 246 | logger.add(s); | |||
| 247 | } | |||
| 248 | public Logger getLogger(){ | |||
| 249 | return logger; | |||
| 250 | } | |||
| 251 | private SingleLockState getServiceOnStart(){ | |||
| 252 | SingleLockState onStart=map.get("onStart"); | |||
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | |||
| 254 | if (onStartCommand == null) { | |||
| 255 | return onStart; | |||
| 256 | } | |||
| 257 | else { | |||
| 258 | return onStartCommand; | |||
| 259 | } | |||
| 260 | } | |||
| 261 | /** | |||
| 262 | * TODO: make sure the same lock is locked and unlocked... | |||
| 263 | */ | |||
| 264 | public void solveFacts(){ | |||
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | |||
| 266 | if (component.getComponentType().equals("Activity")) { | |||
| 267 | SingleLockState onCreateState=map.get("onCreate"); | |||
| 268 | if (locking(onCreateState)) { | |||
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | |||
| 270 | } | |||
| 271 | SingleLockState onStartState=map.get("onStart"); | |||
| 272 | if (locking(onStartState)) { | |||
| 273 | logNote("POSSIBLE BUG: Locking @ onStart"); | |||
| 274 | } | |||
| 275 | SingleLockState onPauseState=map.get("onPause"); | |||
| 276 | SingleLockState onResumeState=map.get("onResume"); | |||
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |||
| 278 | logNote("POSSIBLE BUG(onPause - onResume)"); | |||
| 279 | } | |||
| 280 | } | |||
| 281 | if (component.getComponentType().equals("Service")) { | |||
| 282 | SingleLockState onStartState=getServiceOnStart(); | |||
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | |||
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |||
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |||
| 286 | } | |||
| 287 | if (weakUnlocking(onDestroyState)) { | |||
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |||
| 289 | } | |||
| 290 | } | |||
| 291 | if (component.getComponentType().equals("RunnableThread")) { | |||
| 292 | SingleLockState runState=map.get("run"); | |||
| 293 | if (locking(runState)) { | |||
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |||
| 295 | } | |||
| 296 | } | |||
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | |||
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | |||
| 299 | if (locking(onReceiveState)) { | |||
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |||
| 301 | } | |||
| 130 | } | 302 | } | |
| 131 | } | 303 | } | |
| 132 | } | 304 | } | |
| 133 | } | 305 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_005 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_006 | |||
|---|---|---|---|---|
|
305 lines 11787 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12090 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:38.377 | 1 | //Time : 2012-04-24 18:21:42.137 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 8 | changes = 5 | |||
| 9 | changes to method solveFacts = 1 | |||
| 10 | private/protected method declarations = 1 | |||
| 11 | */package energy.analysis; | |||
| 4 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 16 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 18 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 18 | import energy.util.E; | 26 | import energy.util.E; | |
| 19 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 20 | /** | 28 | /** | |
| 21 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 22 | */ | 30 | */ | |
| 23 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 24 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 25 | private Component component; | 33 | private Component component; | |
| 26 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 27 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 28 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 29 | this.component=c; | 37 | this.component=c; | |
| 30 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 31 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 32 | } | 40 | } | |
| 33 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 34 | return allExitStates; | 42 | return allExitStates; | |
| 35 | } | 43 | } | |
| 36 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 37 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 38 | } | 46 | } | |
| 39 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 40 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 41 | } | 49 | } | |
| 42 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 43 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 44 | } | 52 | } | |
| 45 | public String toString(){ | 53 | public String toString(){ | |
| 46 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 47 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 48 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 49 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 50 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 51 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 52 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 53 | } | 61 | } | |
| 54 | } | 62 | } | |
| 55 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 56 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 57 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 58 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 59 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 60 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 61 | ; | 69 | ; | |
| 62 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 63 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 64 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 65 | } | 73 | } | |
| 66 | } | 74 | } | |
| 67 | } | 75 | } | |
| 68 | } | 76 | } | |
| 69 | return null; | 77 | return null; | |
| 70 | } | 78 | } | |
| 71 | } | 79 | } | |
| 72 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 73 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 74 | } | 82 | } | |
| 75 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 76 | /** | 84 | /** | |
| 77 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 78 | * @param component | 86 | * @param component | |
| 79 | */ | 87 | */ | |
| 80 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 81 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 82 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 83 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 84 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 85 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 86 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 87 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 88 | } | 96 | } | |
| 89 | } | 97 | } | |
| 90 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 91 | } | 99 | } | |
| 92 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 93 | if (runState != null) { | 101 | if (runState != null) { | |
| 94 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 95 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 96 | } | 104 | } | |
| 97 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 98 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 99 | } | 107 | } | |
| 100 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 101 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 102 | } | 110 | } | |
| 103 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 104 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 105 | } | 113 | } | |
| 106 | else { | 114 | else { | |
| 107 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 108 | } | 116 | } | |
| 109 | } | 117 | } | |
| 110 | else { | 118 | else { | |
| 111 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 112 | } | 120 | } | |
| 113 | } | 121 | } | |
| 114 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 115 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 116 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 117 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 118 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 119 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 120 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 121 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 122 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 123 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 124 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 125 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 126 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 127 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 128 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 129 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 130 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 131 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 132 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 133 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 134 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 135 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 136 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 137 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 138 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 139 | printMethod=true; | 147 | printMethod=true; | |
| 140 | } | 148 | } | |
| 141 | } | 149 | } | |
| 142 | if (printMethod) { | 150 | if (printMethod) { | |
| 143 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 144 | printComponent=true; | 152 | printComponent=true; | |
| 145 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 146 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 147 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 148 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 149 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 150 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 151 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 152 | } | 160 | } | |
| 153 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 154 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 155 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 156 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 157 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 158 | } | 166 | } | |
| 159 | else { | 167 | else { | |
| 160 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 161 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 162 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 163 | } | 171 | } | |
| 164 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 165 | } | 173 | } | |
| 166 | } | 174 | } | |
| 167 | } | 175 | } | |
| 168 | } | 176 | } | |
| 169 | if (printComponent) { | 177 | if (printComponent) { | |
| 170 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 171 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 172 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 173 | } | 181 | } | |
| 174 | } | 182 | } | |
| 175 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 176 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 177 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 178 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 179 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 180 | } | 188 | } | |
| 181 | } | 189 | } | |
| 182 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 183 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 184 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 185 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 186 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 187 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 188 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 189 | } | 197 | } | |
| 190 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 191 | } | 199 | } | |
| 192 | return result; | 200 | return result; | |
| 193 | } | 201 | } | |
| 194 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 195 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 196 | public void output(){ | 204 | public void output(){ | |
| 197 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 198 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 199 | } | 207 | } | |
| 200 | } | 208 | } | |
| 201 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 202 | return this; | 210 | return this; | |
| 203 | } | 211 | } | |
| 204 | public String toString(){ | 212 | public String toString(){ | |
| 205 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 206 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 207 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 208 | } | 216 | } | |
| 209 | return result.toString(); | 217 | return result.toString(); | |
| 210 | } | 218 | } | |
| 211 | } | 219 | } | |
| 212 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 213 | private Component component; | 221 | private Component component; | |
| 214 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 215 | this.component=component; | 223 | this.component=component; | |
| 216 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 217 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 218 | } | 226 | } | |
| 219 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 220 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 221 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 222 | } | 230 | } | |
| 223 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 224 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 225 | } | 233 | } | |
| 226 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 227 | if (state != null) { | 235 | if (state != null) { | |
| 228 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 229 | } | 237 | } | |
| 230 | return false; | 238 | return false; | |
| 231 | } | 239 | } | |
| 232 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 241 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 235 | } | 243 | } | |
| 236 | return false; | 244 | return false; | |
| 237 | } | 245 | } | |
| 238 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 239 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 240 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 241 | } | 249 | } | |
| 242 | return false; | 250 | return false; | |
| 243 | } | 251 | } | |
| 244 | private Logger logger; | 252 | private Logger logger; | |
| 245 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 246 | logger.add(s); | 254 | logger.add(s); | |
| 247 | } | 255 | } | |
| 248 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 249 | return logger; | 257 | return logger; | |
| 250 | } | 258 | } | |
| 251 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 252 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 253 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 254 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 255 | return onStart; | 263 | return onStart; | |
| 256 | } | 264 | } | |
| 257 | else { | 265 | else { | |
| 258 | return onStartCommand; | 266 | return onStartCommand; | |
| 259 | } | 267 | } | |
| 260 | } | 268 | } | |
| 261 | /** | 269 | /** | |
| 262 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 263 | */ | 271 | */ | |
| 264 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 265 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 266 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 267 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 268 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 269 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 270 | } | 278 | } | |
| 271 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 272 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 273 | logNote("POSSIBLE BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 274 | } | 282 | } | |
| 275 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 276 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 277 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 278 | logNote("POSSIBLE BUG(onPause - onResume)"); | 286 | logNote("POSSIBLE BUG(onPause - onResume)"); | |
| 279 | } | 287 | } | |
| 280 | } | 288 | } | |
| 281 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 282 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 283 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 284 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 285 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 286 | } | 294 | } | |
| 287 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 288 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 289 | } | 297 | } | |
| 290 | } | 298 | } | |
| 291 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 292 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 293 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 295 | } | 303 | } | |
| 296 | } | 304 | } | |
| 297 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 298 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 299 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 301 | } | 309 | } | |
| 302 | } | 310 | } | |
| 303 | } | 311 | } | |
| 304 | } | 312 | } | |
| 305 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_006 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_007 | |||
|---|---|---|---|---|
|
313 lines 12090 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12088 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:42.137 | 1 | //Time : 2012-04-24 18:21:49.371 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("POSSIBLE BUG(onPause - onResume)"); | 286 | logNote("STRONG BUG(onPause - onResume)"); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_007 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_008 | |||
|---|---|---|---|---|
|
313 lines 12088 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12089 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:49.371 | 1 | //Time : 2012-04-24 18:21:54.118 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG(onPause - onResume)"); | 286 | logNote("STRONG BUG: onPause - onResume)"); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_008 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_009 | |||
|---|---|---|---|---|
|
313 lines 12089 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12088 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:54.118 | 1 | //Time : 2012-04-24 18:21:55.584 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG: onPause - onResume)"); | 286 | logNote("STRONG BUG: onPause - onResume"); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_009 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_010 | |||
|---|---|---|---|---|
|
313 lines 12088 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12091 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:21:55.584 | 1 | //Time : 2012-04-24 18:22:00.338 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG: onPause - onResume"); | 286 | logNote("STRONG BUG: onPause - onResume ()"); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_010 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_011 | |||
|---|---|---|---|---|
|
313 lines 12091 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12090 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:00.338 | 1 | //Time : 2012-04-24 18:22:02.144 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG: onPause - onResume ()"); | 286 | logNote("STRONG BUG: onPause - onResume ("); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_011 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_012 | |||
|---|---|---|---|---|
|
313 lines 12090 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12119 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:02.144 | 1 | //Time : 2012-04-24 18:22:06.889 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG: onPause - onResume ("); | 286 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_012 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_013 | |||
|---|---|---|---|---|
|
313 lines 12119 bytes Last modified : Mon May 14 23:48:02 2012 |
313 lines 12150 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:06.889 | 1 | //Time : 2012-04-24 18:22:28.193 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 277 | logNote("STRONG BUG: Locking @ onCreate"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 283 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 284 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 286 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 287 | } | 287 | } | |
| 288 | } | 288 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 289 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 290 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 291 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 294 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 295 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | } | 298 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 299 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 300 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 301 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 306 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 307 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_013 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_015 | |||
|---|---|---|---|---|
|
313 lines 12150 bytes Last modified : Mon May 14 23:48:02 2012 |
311 lines 12105 bytes Last modified : Mon May 14 23:48:02 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:28.193 | 1 | //Time : 2012-04-24 18:22:31.743 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 6 | changes = 2 | |
| 9 | changes to method solveFacts = 1 | 7 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 8 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 9 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 10 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 11 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 12 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 13 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 14 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 15 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 16 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 17 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 18 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 19 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 20 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 21 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 22 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 23 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 24 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 28 | /** | 26 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 28 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 33 | private Component component; | 31 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 35 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 38 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 40 | return allExitStates; | |
| 43 | } | 41 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 46 | } | 44 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 49 | } | 47 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 52 | } | 50 | } | |
| 53 | public String toString(){ | 51 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 59 | } | |
| 62 | } | 60 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 69 | ; | 67 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 71 | } | |
| 74 | } | 72 | } | |
| 75 | } | 73 | } | |
| 76 | } | 74 | } | |
| 77 | return null; | 75 | return null; | |
| 78 | } | 76 | } | |
| 79 | } | 77 | } | |
| 80 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 80 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 82 | /** | |
| 85 | * Invoke this after the component has been analyzed | 83 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 84 | * @param component | |
| 87 | */ | 85 | */ | |
| 88 | public void createComponentSummary( Component component){ | 86 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 87 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 88 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 89 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 90 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 91 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 92 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 93 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 94 | } | |
| 97 | } | 95 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 96 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 97 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 98 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 99 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 100 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 101 | return LockUsage.LOCKING; | |
| 104 | } | 102 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 103 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 104 | return LockUsage.EMPTY; | |
| 107 | } | 105 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 106 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 107 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 108 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 109 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 110 | return LockUsage.UNLOCKING; | |
| 113 | } | 111 | } | |
| 114 | else { | 112 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 113 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 114 | } | |
| 117 | } | 115 | } | |
| 118 | else { | 116 | else { | |
| 119 | return LockUsage.EMPTY; | 117 | return LockUsage.EMPTY; | |
| 120 | } | 118 | } | |
| 121 | } | 119 | } | |
| 122 | public ArrayList<String> processResults(){ | 120 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 121 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 122 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 123 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 124 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 125 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 126 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 127 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 128 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 129 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 130 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 131 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 132 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 133 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 134 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 135 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 136 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 137 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 138 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 139 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 140 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 141 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 142 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 143 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 144 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 145 | printMethod=true; | |
| 148 | } | 146 | } | |
| 149 | } | 147 | } | |
| 150 | if (printMethod) { | 148 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 149 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 150 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 151 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 152 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 153 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 154 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 155 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 156 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 157 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 158 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 159 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 160 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 161 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 162 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 163 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 164 | } | |
| 167 | else { | 165 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 166 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 167 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 168 | usageMap.put(lu,set); | |
| 171 | } | 169 | } | |
| 172 | policy.addFact(node,mergedLS); | 170 | policy.addFact(node,mergedLS); | |
| 173 | } | 171 | } | |
| 174 | } | 172 | } | |
| 175 | } | 173 | } | |
| 176 | } | 174 | } | |
| 177 | if (printComponent) { | 175 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 176 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 177 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 178 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 179 | } | |
| 182 | } | 180 | } | |
| 183 | System.out.println("==========================================\n"); | 181 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 182 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 183 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 184 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 185 | System.out.println(" " + s.toString()); | |
| 188 | } | 186 | } | |
| 189 | } | 187 | } | |
| 190 | System.out.println("==========================================\n"); | 188 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 189 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 190 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 191 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 192 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 193 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 194 | System.out.println("\n"); | |
| 197 | } | 195 | } | |
| 198 | result=logger.getStringList(); | 196 | result=logger.getStringList(); | |
| 199 | } | 197 | } | |
| 200 | return result; | 198 | return result; | |
| 201 | } | 199 | } | |
| 202 | public class Logger extends ArrayList<String> { | 200 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 201 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 202 | public void output(){ | |
| 205 | for ( String s : this) { | 203 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 204 | System.out.println(" " + s); | |
| 207 | } | 205 | } | |
| 208 | } | 206 | } | |
| 209 | public ArrayList<String> getStringList(){ | 207 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 208 | return this; | |
| 211 | } | 209 | } | |
| 212 | public String toString(){ | 210 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 211 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 212 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 213 | result.append(s + "\n"); | |
| 216 | } | 214 | } | |
| 217 | return result.toString(); | 215 | return result.toString(); | |
| 218 | } | 216 | } | |
| 219 | } | 217 | } | |
| 220 | public class ComponentPolicy { | 218 | public class ComponentPolicy { | |
| 221 | private Component component; | 219 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 220 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 221 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 222 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 223 | logger=new Logger(); | |
| 226 | } | 224 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 225 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 226 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 227 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 228 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 229 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 230 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 231 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 232 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 233 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 234 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 235 | } | |
| 238 | return false; | 236 | return false; | |
| 239 | } | 237 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 238 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 239 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 240 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 241 | } | |
| 244 | return false; | 242 | return false; | |
| 245 | } | 243 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 244 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 245 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 246 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 247 | } | |
| 250 | return false; | 248 | return false; | |
| 251 | } | 249 | } | |
| 252 | private Logger logger; | 250 | private Logger logger; | |
| 253 | private void logNote( String s){ | 251 | private void logNote( String s){ | |
| 254 | logger.add(s); | 252 | logger.add(s); | |
| 255 | } | 253 | } | |
| 256 | public Logger getLogger(){ | 254 | public Logger getLogger(){ | |
| 257 | return logger; | 255 | return logger; | |
| 258 | } | 256 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 257 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 258 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 259 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 260 | if (onStartCommand == null) { | |
| 263 | return onStart; | 261 | return onStart; | |
| 264 | } | 262 | } | |
| 265 | else { | 263 | else { | |
| 266 | return onStartCommand; | 264 | return onStartCommand; | |
| 267 | } | 265 | } | |
| 268 | } | 266 | } | |
| 269 | /** | 267 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 268 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 269 | */ | |
| 272 | public void solveFacts(){ | 270 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 271 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 272 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 273 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 274 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate"); | 275 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 276 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 277 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 278 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 279 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 280 | } | |
| 283 | SingleLockState onPauseState=map.get("onPause"); | 281 | SingleLockState onPauseState=map.get("onPause"); | |
| 284 | SingleLockState onResumeState=map.get("onResume"); | 282 | SingleLockState onResumeState=map.get("onResume"); | |
| 285 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 283 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 286 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 287 | } | 285 | } | |
| 288 | } | 286 | } | |
| 289 | if (component.getComponentType().equals("Service")) { | 287 | if (component.getComponentType().equals("Service")) { | |
| 290 | SingleLockState onStartState=getServiceOnStart(); | 288 | SingleLockState onStartState=getServiceOnStart(); | |
| 291 | SingleLockState onDestroyState=map.get("onDestroy"); | 289 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 292 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 290 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 293 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 291 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 294 | } | 292 | } | |
| 295 | if (weakUnlocking(onDestroyState)) { | 293 | if (weakUnlocking(onDestroyState)) { | |
| 296 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 294 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 297 | } | 295 | } | |
| 298 | } | 296 | } | |
| 299 | if (component.getComponentType().equals("RunnableThread")) { | 297 | if (component.getComponentType().equals("RunnableThread")) { | |
| 300 | SingleLockState runState=map.get("run"); | 298 | SingleLockState runState=map.get("run"); | |
| 301 | if (locking(runState)) { | 299 | if (locking(runState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 303 | } | 301 | } | |
| 304 | } | 302 | } | |
| 305 | if (component.getComponentType().equals("BroadcastReceiver")) { | 303 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 306 | SingleLockState onReceiveState=map.get("onReceive"); | 304 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 307 | if (locking(onReceiveState)) { | 305 | if (locking(onReceiveState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 309 | } | 307 | } | |
| 310 | } | 308 | } | |
| 311 | } | 309 | } | |
| 312 | } | 310 | } | |
| 313 | } | 311 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_015 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_016 | |||
|---|---|---|---|---|
|
311 lines 12105 bytes Last modified : Mon May 14 23:48:02 2012 |
318 lines 12368 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:22:31.743 | 1 | //Time : 2012-04-24 18:27:17.387 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 1 | |||
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | changes = 2 | 7 | INSERT ExpressionStmt IfStmt = 1 | |
| 8 | changes = 3 | |||
| 7 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | inserts = 1 | |||
| 8 | private/protected method declarations = 1 | 11 | private/protected method declarations = 1 | |
| 9 | */package energy.analysis; | 12 | */package energy.analysis; | |
| 10 | import java.util.ArrayList; | 13 | import java.util.ArrayList; | |
| 11 | import java.util.HashMap; | 14 | import java.util.HashMap; | |
| 12 | import java.util.HashSet; | 15 | import java.util.HashSet; | |
| 13 | import java.util.Iterator; | 16 | import java.util.Iterator; | |
| 14 | import java.util.Map; | 17 | import java.util.Map; | |
| 15 | import java.util.Map.Entry; | 18 | import java.util.Map.Entry; | |
| 16 | import java.util.Set; | 19 | import java.util.Set; | |
| 17 | import com.ibm.wala.ipa.callgraph.CGNode; | 20 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 18 | import com.ibm.wala.util.collections.Pair; | 21 | import com.ibm.wala.util.collections.Pair; | |
| 19 | import energy.analysis.WakeLockManager.WakeLockInstance; | 22 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 20 | import energy.components.Component; | 23 | import energy.components.Component; | |
| 21 | import energy.components.Component.CallBack; | 24 | import energy.components.Component.CallBack; | |
| 22 | import energy.interproc.CompoundLockState; | 25 | import energy.interproc.CompoundLockState; | |
| 23 | import energy.interproc.SingleLockState; | 26 | import energy.interproc.SingleLockState; | |
| 24 | import energy.util.E; | 27 | import energy.util.E; | |
| 25 | public class AnalysisResults { | 28 | public class AnalysisResults { | |
| 26 | /** | 29 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 30 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 31 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 32 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 33 | public class ComponentSummary { | |
| 31 | private Component component; | 34 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 35 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 36 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 37 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 38 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 39 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 40 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 41 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 42 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 43 | return allExitStates; | |
| 41 | } | 44 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 45 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 46 | allExitStates.put(n,st); | |
| 44 | } | 47 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 48 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 49 | callBackExitStates.put(cb,st); | |
| 47 | } | 50 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 51 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 52 | return allExitStates.get(method); | |
| 50 | } | 53 | } | |
| 51 | public String toString(){ | 54 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 55 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 56 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 57 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 58 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 59 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 60 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 61 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 62 | } | |
| 60 | } | 63 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 64 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 65 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 66 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 67 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 68 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 69 | String name=cb.getName(); | |
| 67 | ; | 70 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 71 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 72 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 73 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 74 | } | |
| 72 | } | 75 | } | |
| 73 | } | 76 | } | |
| 74 | } | 77 | } | |
| 75 | return null; | 78 | return null; | |
| 76 | } | 79 | } | |
| 77 | } | 80 | } | |
| 78 | public AnalysisResults(){ | 81 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 82 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 83 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 84 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | /** | 85 | /** | |
| 83 | * Invoke this after the component has been analyzed | 86 | * Invoke this after the component has been analyzed | |
| 84 | * @param component | 87 | * @param component | |
| 85 | */ | 88 | */ | |
| 86 | public void createComponentSummary( Component component){ | 89 | public void createComponentSummary( Component component){ | |
| 87 | ComponentSummary componentSummary=new ComponentSummary(component); | 90 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 88 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 91 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 89 | CGNode next=it.next(); | 92 | CGNode next=it.next(); | |
| 90 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 93 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 91 | if (exitState != null) { | 94 | if (exitState != null) { | |
| 92 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 95 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 93 | componentSummary.registerNodeState(next,compoundLockState); | 96 | componentSummary.registerNodeState(next,compoundLockState); | |
| 94 | } | 97 | } | |
| 95 | } | 98 | } | |
| 96 | allStates.add(Pair.make(component,componentSummary)); | 99 | allStates.add(Pair.make(component,componentSummary)); | |
| 97 | } | 100 | } | |
| 98 | private LockUsage getLockUsage( SingleLockState runState){ | 101 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 99 | if (runState != null) { | 102 | if (runState != null) { | |
| 100 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 103 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 101 | return LockUsage.LOCKING; | 104 | return LockUsage.LOCKING; | |
| 102 | } | 105 | } | |
| 103 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 106 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 104 | return LockUsage.EMPTY; | 107 | return LockUsage.EMPTY; | |
| 105 | } | 108 | } | |
| 106 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 109 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 107 | return LockUsage.FULL_UNLOCKING; | 110 | return LockUsage.FULL_UNLOCKING; | |
| 108 | } | 111 | } | |
| 109 | else if (runState.isMaybeReleased()) { | 112 | else if (runState.isMaybeReleased()) { | |
| 110 | return LockUsage.UNLOCKING; | 113 | return LockUsage.UNLOCKING; | |
| 111 | } | 114 | } | |
| 112 | else { | 115 | else { | |
| 113 | return LockUsage.UNKNOWN_STATE; | 116 | return LockUsage.UNKNOWN_STATE; | |
| 114 | } | 117 | } | |
| 115 | } | 118 | } | |
| 116 | else { | 119 | else { | |
| 117 | return LockUsage.EMPTY; | 120 | return LockUsage.EMPTY; | |
| 118 | } | 121 | } | |
| 119 | } | 122 | } | |
| 120 | public ArrayList<String> processResults(){ | 123 | public ArrayList<String> processResults(){ | |
| 121 | ArrayList<String> result=null; | 124 | ArrayList<String> result=null; | |
| 122 | System.out.println("\n=========================================="); | 125 | System.out.println("\n=========================================="); | |
| 123 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 126 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 124 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 127 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 125 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 128 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 126 | Component component=pair.fst; | 129 | Component component=pair.fst; | |
| 127 | ComponentSummary cSummary=pair.snd; | 130 | ComponentSummary cSummary=pair.snd; | |
| 128 | ComponentPolicy policy=new ComponentPolicy(component); | 131 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 129 | StringBuffer sb=new StringBuffer(); | 132 | StringBuffer sb=new StringBuffer(); | |
| 130 | boolean printComponent=false; | 133 | boolean printComponent=false; | |
| 131 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 134 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 132 | CGNode node=e.getKey(); | 135 | CGNode node=e.getKey(); | |
| 133 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 136 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 134 | boolean printMethod=false; | 137 | boolean printMethod=false; | |
| 135 | LockUsage lockUsage=LockUsage.EMPTY; | 138 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 136 | CompoundLockState compLS=e.getValue(); | 139 | CompoundLockState compLS=e.getValue(); | |
| 137 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 140 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 138 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 141 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 139 | WakeLockInstance wli=fs.getKey(); | 142 | WakeLockInstance wli=fs.getKey(); | |
| 140 | Set<SingleLockState> sls=fs.getValue(); | 143 | Set<SingleLockState> sls=fs.getValue(); | |
| 141 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 144 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 142 | lockUsage=getLockUsage(sl); | 145 | lockUsage=getLockUsage(sl); | |
| 143 | lockUsages.put(wli,lockUsage); | 146 | lockUsages.put(wli,lockUsage); | |
| 144 | if (lockUsage != LockUsage.EMPTY) { | 147 | if (lockUsage != LockUsage.EMPTY) { | |
| 145 | printMethod=true; | 148 | printMethod=true; | |
| 146 | } | 149 | } | |
| 147 | } | 150 | } | |
| 148 | if (printMethod) { | 151 | if (printMethod) { | |
| 149 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 152 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 150 | printComponent=true; | 153 | printComponent=true; | |
| 151 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 154 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 152 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 155 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 153 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 154 | WakeLockInstance key=fs.getKey(); | 157 | WakeLockInstance key=fs.getKey(); | |
| 155 | Set<SingleLockState> value=fs.getValue(); | 158 | Set<SingleLockState> value=fs.getValue(); | |
| 156 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 159 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 157 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 160 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 158 | } | 161 | } | |
| 159 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 162 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 160 | LockUsage lu=getLockUsage(mergedLS); | 163 | LockUsage lu=getLockUsage(mergedLS); | |
| 161 | if (component.isCallBack(node)) { | 164 | if (component.isCallBack(node)) { | |
| 162 | if (usageMap.containsKey(lu)) { | 165 | if (usageMap.containsKey(lu)) { | |
| 163 | usageMap.get(lu).add(Pair.make(component,node)); | 166 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 164 | } | 167 | } | |
| 165 | else { | 168 | else { | |
| 166 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 169 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 167 | set.add(Pair.make(component,node)); | 170 | set.add(Pair.make(component,node)); | |
| 168 | usageMap.put(lu,set); | 171 | usageMap.put(lu,set); | |
| 169 | } | 172 | } | |
| 170 | policy.addFact(node,mergedLS); | 173 | policy.addFact(node,mergedLS); | |
| 171 | } | 174 | } | |
| 172 | } | 175 | } | |
| 173 | } | 176 | } | |
| 174 | } | 177 | } | |
| 175 | if (printComponent) { | 178 | if (printComponent) { | |
| 176 | System.out.println(component.toString() + "\n" + sb.toString()); | 179 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 177 | policy.solveFacts(); | 180 | policy.solveFacts(); | |
| 178 | componentMap.put(component,policy.getLogger()); | 181 | componentMap.put(component,policy.getLogger()); | |
| 179 | } | 182 | } | |
| 180 | } | 183 | } | |
| 181 | System.out.println("==========================================\n"); | 184 | System.out.println("==========================================\n"); | |
| 182 | for ( LockUsage e : usageMap.keySet()) { | 185 | for ( LockUsage e : usageMap.keySet()) { | |
| 183 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 184 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 187 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 185 | System.out.println(" " + s.toString()); | 188 | System.out.println(" " + s.toString()); | |
| 186 | } | 189 | } | |
| 187 | } | 190 | } | |
| 188 | System.out.println("==========================================\n"); | 191 | System.out.println("==========================================\n"); | |
| 189 | for ( Component e : componentMap.keySet()) { | 192 | for ( Component e : componentMap.keySet()) { | |
| 190 | Logger logger=componentMap.get(e); | 193 | Logger logger=componentMap.get(e); | |
| 191 | if (!logger.isEmpty()) { | 194 | if (!logger.isEmpty()) { | |
| 192 | System.out.println(e.toString()); | 195 | System.out.println(e.toString()); | |
| 193 | System.out.println(logger.toString()); | 196 | System.out.println(logger.toString()); | |
| 194 | System.out.println("\n"); | 197 | System.out.println("\n"); | |
| 195 | } | 198 | } | |
| 196 | result=logger.getStringList(); | 199 | result=logger.getStringList(); | |
| 197 | } | 200 | } | |
| 198 | return result; | 201 | return result; | |
| 199 | } | 202 | } | |
| 200 | public class Logger extends ArrayList<String> { | 203 | public class Logger extends ArrayList<String> { | |
| 201 | private static final long serialVersionUID=4402714524487791090L; | 204 | private static final long serialVersionUID=4402714524487791090L; | |
| 202 | public void output(){ | 205 | public void output(){ | |
| 203 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 204 | System.out.println(" " + s); | 207 | System.out.println(" " + s); | |
| 205 | } | 208 | } | |
| 206 | } | 209 | } | |
| 207 | public ArrayList<String> getStringList(){ | 210 | public ArrayList<String> getStringList(){ | |
| 208 | return this; | 211 | return this; | |
| 209 | } | 212 | } | |
| 210 | public String toString(){ | 213 | public String toString(){ | |
| 211 | StringBuffer result=new StringBuffer(); | 214 | StringBuffer result=new StringBuffer(); | |
| 212 | for ( String s : this) { | 215 | for ( String s : this) { | |
| 213 | result.append(s + "\n"); | 216 | result.append(s + "\n"); | |
| 214 | } | 217 | } | |
| 215 | return result.toString(); | 218 | return result.toString(); | |
| 216 | } | 219 | } | |
| 217 | } | 220 | } | |
| 218 | public class ComponentPolicy { | 221 | public class ComponentPolicy { | |
| 219 | private Component component; | 222 | private Component component; | |
| 220 | public ComponentPolicy( Component component){ | 223 | public ComponentPolicy( Component component){ | |
| 221 | this.component=component; | 224 | this.component=component; | |
| 222 | map=new HashMap<String,SingleLockState>(); | 225 | map=new HashMap<String,SingleLockState>(); | |
| 223 | logger=new Logger(); | 226 | logger=new Logger(); | |
| 224 | } | 227 | } | |
| 225 | private HashMap<String,SingleLockState> map; | 228 | private HashMap<String,SingleLockState> map; | |
| 226 | public void addFact( CGNode n, SingleLockState st){ | 229 | public void addFact( CGNode n, SingleLockState st){ | |
| 227 | map.put(n.getMethod().getName().toString(),st); | 230 | map.put(n.getMethod().getName().toString(),st); | |
| 228 | } | 231 | } | |
| 229 | private boolean unlocking( SingleLockState state){ | 232 | private boolean unlocking( SingleLockState state){ | |
| 230 | return (strongUnlocking(state) || weakUnlocking(state)); | 233 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 231 | } | 234 | } | |
| 232 | private boolean strongUnlocking( SingleLockState state){ | 235 | private boolean strongUnlocking( SingleLockState state){ | |
| 233 | if (state != null) { | 236 | if (state != null) { | |
| 234 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 237 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 235 | } | 238 | } | |
| 236 | return false; | 239 | return false; | |
| 237 | } | 240 | } | |
| 238 | private boolean weakUnlocking( SingleLockState state){ | 241 | private boolean weakUnlocking( SingleLockState state){ | |
| 239 | if (state != null) { | 242 | if (state != null) { | |
| 240 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 243 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 241 | } | 244 | } | |
| 242 | return false; | 245 | return false; | |
| 243 | } | 246 | } | |
| 244 | private boolean locking( SingleLockState onCreateState){ | 247 | private boolean locking( SingleLockState onCreateState){ | |
| 245 | if (onCreateState != null) { | 248 | if (onCreateState != null) { | |
| 246 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 249 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 247 | } | 250 | } | |
| 248 | return false; | 251 | return false; | |
| 249 | } | 252 | } | |
| 250 | private Logger logger; | 253 | private Logger logger; | |
| 251 | private void logNote( String s){ | 254 | private void logNote( String s){ | |
| 252 | logger.add(s); | 255 | logger.add(s); | |
| 253 | } | 256 | } | |
| 254 | public Logger getLogger(){ | 257 | public Logger getLogger(){ | |
| 255 | return logger; | 258 | return logger; | |
| 256 | } | 259 | } | |
| 257 | private SingleLockState getServiceOnStart(){ | 260 | private SingleLockState getServiceOnStart(){ | |
| 258 | SingleLockState onStart=map.get("onStart"); | 261 | SingleLockState onStart=map.get("onStart"); | |
| 259 | SingleLockState onStartCommand=map.get("onStartCommand"); | 262 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 260 | if (onStartCommand == null) { | 263 | if (onStartCommand == null) { | |
| 261 | return onStart; | 264 | return onStart; | |
| 262 | } | 265 | } | |
| 263 | else { | 266 | else { | |
| 264 | return onStartCommand; | 267 | return onStartCommand; | |
| 265 | } | 268 | } | |
| 266 | } | 269 | } | |
| 267 | /** | 270 | /** | |
| 268 | * TODO: make sure the same lock is locked and unlocked... | 271 | * TODO: make sure the same lock is locked and unlocked... | |
| 269 | */ | 272 | */ | |
| 270 | public void solveFacts(){ | 273 | public void solveFacts(){ | |
| 271 | E.log(1,"Looking for: " + component.getComponentType()); | 274 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 272 | if (component.getComponentType().equals("Activity")) { | 275 | if (component.getComponentType().equals("Activity")) { | |
| 273 | SingleLockState onCreateState=map.get("onCreate"); | 276 | SingleLockState onCreateState=map.get("onCreate"); | |
| 274 | if (locking(onCreateState)) { | 277 | if (locking(onCreateState)) { | |
| 275 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 278 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 276 | } | 279 | } | |
| 277 | SingleLockState onStartState=map.get("onStart"); | 280 | SingleLockState onStartState=map.get("onStart"); | |
| 278 | if (locking(onStartState)) { | 281 | if (locking(onStartState)) { | |
| 279 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 280 | } | 283 | } | |
| 284 | SingleLockState onStartState=map.get("onStart"); | |||
| 285 | if (locking(onStartState)) { | |||
| 286 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |||
| 287 | } | |||
| 281 | SingleLockState onPauseState=map.get("onPause"); | 288 | SingleLockState onPauseState=map.get("onPause"); | |
| 282 | SingleLockState onResumeState=map.get("onResume"); | 289 | SingleLockState onResumeState=map.get("onResume"); | |
| 283 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 290 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 284 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 291 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 285 | } | 292 | } | |
| 286 | } | 293 | } | |
| 287 | if (component.getComponentType().equals("Service")) { | 294 | if (component.getComponentType().equals("Service")) { | |
| 288 | SingleLockState onStartState=getServiceOnStart(); | 295 | SingleLockState onStartState=getServiceOnStart(); | |
| 289 | SingleLockState onDestroyState=map.get("onDestroy"); | 296 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 290 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 297 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 291 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 298 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 292 | } | 299 | } | |
| 293 | if (weakUnlocking(onDestroyState)) { | 300 | if (weakUnlocking(onDestroyState)) { | |
| 294 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 301 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 295 | } | 302 | } | |
| 296 | } | 303 | } | |
| 297 | if (component.getComponentType().equals("RunnableThread")) { | 304 | if (component.getComponentType().equals("RunnableThread")) { | |
| 298 | SingleLockState runState=map.get("run"); | 305 | SingleLockState runState=map.get("run"); | |
| 299 | if (locking(runState)) { | 306 | if (locking(runState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 307 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 301 | } | 308 | } | |
| 302 | } | 309 | } | |
| 303 | if (component.getComponentType().equals("BroadcastReceiver")) { | 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 304 | SingleLockState onReceiveState=map.get("onReceive"); | 311 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 305 | if (locking(onReceiveState)) { | 312 | if (locking(onReceiveState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 307 | } | 314 | } | |
| 308 | } | 315 | } | |
| 309 | } | 316 | } | |
| 310 | } | 317 | } | |
| 311 | } | 318 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_016 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_017 | |||
|---|---|---|---|---|
|
318 lines 12368 bytes Last modified : Mon May 14 23:48:03 2012 |
317 lines 12370 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:17.387 | 1 | //Time : 2012-04-24 18:27:20.898 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 5 | CHANGE IfStmt to IfStmt = 1 | 6 | CHANGE IfStmt to IfStmt = 1 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | INSERT ExpressionStmt IfStmt = 1 | 8 | changes = 4 | |
| 8 | changes = 3 | |||
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | inserts = 1 | |||
| 11 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 12 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 13 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 14 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 15 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 16 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 17 | import java.util.Map; | 16 | import java.util.Map; | |
| 18 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 19 | import java.util.Set; | 18 | import java.util.Set; | |
| 20 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 21 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 22 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 23 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 24 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 25 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 26 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 27 | import energy.util.E; | 26 | import energy.util.E; | |
| 28 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 29 | /** | 28 | /** | |
| 30 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 31 | */ | 30 | */ | |
| 32 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 33 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 34 | private Component component; | 33 | private Component component; | |
| 35 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 36 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 37 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 38 | this.component=c; | 37 | this.component=c; | |
| 39 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 40 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 41 | } | 40 | } | |
| 42 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 43 | return allExitStates; | 42 | return allExitStates; | |
| 44 | } | 43 | } | |
| 45 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 46 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 47 | } | 46 | } | |
| 48 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 49 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 50 | } | 49 | } | |
| 51 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 52 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 53 | } | 52 | } | |
| 54 | public String toString(){ | 53 | public String toString(){ | |
| 55 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 56 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 57 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 58 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 59 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 60 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 61 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 62 | } | 61 | } | |
| 63 | } | 62 | } | |
| 64 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 65 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 66 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 67 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 68 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 69 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 70 | ; | 69 | ; | |
| 71 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 72 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 73 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | } | 76 | } | |
| 78 | return null; | 77 | return null; | |
| 79 | } | 78 | } | |
| 80 | } | 79 | } | |
| 81 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 82 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 83 | } | 82 | } | |
| 84 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 85 | /** | 84 | /** | |
| 86 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 87 | * @param component | 86 | * @param component | |
| 88 | */ | 87 | */ | |
| 89 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 90 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 91 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 92 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 93 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 94 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 95 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 96 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 97 | } | 96 | } | |
| 98 | } | 97 | } | |
| 99 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 100 | } | 99 | } | |
| 101 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 102 | if (runState != null) { | 101 | if (runState != null) { | |
| 103 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 104 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 105 | } | 104 | } | |
| 106 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 107 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 108 | } | 107 | } | |
| 109 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 110 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 111 | } | 110 | } | |
| 112 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 113 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 114 | } | 113 | } | |
| 115 | else { | 114 | else { | |
| 116 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 117 | } | 116 | } | |
| 118 | } | 117 | } | |
| 119 | else { | 118 | else { | |
| 120 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 121 | } | 120 | } | |
| 122 | } | 121 | } | |
| 123 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 124 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 125 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 126 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 127 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 128 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 129 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 130 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 131 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 132 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 133 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 134 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 135 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 136 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 137 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 138 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 139 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 140 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 141 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 142 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 143 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 144 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 145 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 146 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 147 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 148 | printMethod=true; | 147 | printMethod=true; | |
| 149 | } | 148 | } | |
| 150 | } | 149 | } | |
| 151 | if (printMethod) { | 150 | if (printMethod) { | |
| 152 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 153 | printComponent=true; | 152 | printComponent=true; | |
| 154 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 155 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 157 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 158 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 159 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 160 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 161 | } | 160 | } | |
| 162 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 163 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 164 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 165 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 166 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 167 | } | 166 | } | |
| 168 | else { | 167 | else { | |
| 169 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 170 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 171 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 172 | } | 171 | } | |
| 173 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | } | 176 | } | |
| 178 | if (printComponent) { | 177 | if (printComponent) { | |
| 179 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 180 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 181 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 182 | } | 181 | } | |
| 183 | } | 182 | } | |
| 184 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 185 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 186 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 187 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 188 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 189 | } | 188 | } | |
| 190 | } | 189 | } | |
| 191 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 192 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 193 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 194 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 195 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 196 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 197 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 198 | } | 197 | } | |
| 199 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 200 | } | 199 | } | |
| 201 | return result; | 200 | return result; | |
| 202 | } | 201 | } | |
| 203 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 204 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 205 | public void output(){ | 204 | public void output(){ | |
| 206 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 207 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 208 | } | 207 | } | |
| 209 | } | 208 | } | |
| 210 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 211 | return this; | 210 | return this; | |
| 212 | } | 211 | } | |
| 213 | public String toString(){ | 212 | public String toString(){ | |
| 214 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 215 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 216 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 217 | } | 216 | } | |
| 218 | return result.toString(); | 217 | return result.toString(); | |
| 219 | } | 218 | } | |
| 220 | } | 219 | } | |
| 221 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 222 | private Component component; | 221 | private Component component; | |
| 223 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 224 | this.component=component; | 223 | this.component=component; | |
| 225 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 226 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 227 | } | 226 | } | |
| 228 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 229 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 230 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 231 | } | 230 | } | |
| 232 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 233 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 234 | } | 233 | } | |
| 235 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 236 | if (state != null) { | 235 | if (state != null) { | |
| 237 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 238 | } | 237 | } | |
| 239 | return false; | 238 | return false; | |
| 240 | } | 239 | } | |
| 241 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 242 | if (state != null) { | 241 | if (state != null) { | |
| 243 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 244 | } | 243 | } | |
| 245 | return false; | 244 | return false; | |
| 246 | } | 245 | } | |
| 247 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 248 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 249 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 250 | } | 249 | } | |
| 251 | return false; | 250 | return false; | |
| 252 | } | 251 | } | |
| 253 | private Logger logger; | 252 | private Logger logger; | |
| 254 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 255 | logger.add(s); | 254 | logger.add(s); | |
| 256 | } | 255 | } | |
| 257 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 258 | return logger; | 257 | return logger; | |
| 259 | } | 258 | } | |
| 260 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 261 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 262 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 263 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 264 | return onStart; | 263 | return onStart; | |
| 265 | } | 264 | } | |
| 266 | else { | 265 | else { | |
| 267 | return onStartCommand; | 266 | return onStartCommand; | |
| 268 | } | 267 | } | |
| 269 | } | 268 | } | |
| 270 | /** | 269 | /** | |
| 271 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 272 | */ | 271 | */ | |
| 273 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 274 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 275 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 276 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 277 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 278 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 279 | } | 278 | } | |
| 280 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 281 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 282 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 283 | } | 282 | } | |
| 284 | SingleLockState onStartState=map.get("onStart"); | 283 | SingleLockState onReStartState=map.get("onStart"); | |
| 285 | if (locking(onStartState)) { | 284 | if (locking(onStartState)) { | |
| 286 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 287 | } | 286 | } | |
| 288 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 289 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 290 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 291 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 292 | } | 291 | } | |
| 293 | } | 292 | } | |
| 294 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 295 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 296 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 297 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 298 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 299 | } | 298 | } | |
| 300 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 301 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 302 | } | 301 | } | |
| 303 | } | 302 | } | |
| 304 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 305 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 306 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 307 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 308 | } | 307 | } | |
| 309 | } | 308 | } | |
| 310 | if (component.getComponentType().equals("BroadcastReceiver")) { | 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 311 | SingleLockState onReceiveState=map.get("onReceive"); | 310 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 312 | if (locking(onReceiveState)) { | 311 | if (locking(onReceiveState)) { | |
| 313 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 314 | } | 313 | } | |
| 315 | } | 314 | } | |
| 316 | } | 315 | } | |
| 317 | } | 316 | } | |
| 318 | } | 317 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_017 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_018 | |||
|---|---|---|---|---|
|
317 lines 12370 bytes Last modified : Mon May 14 23:48:03 2012 |
317 lines 12370 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:20.898 | 1 | //Time : 2012-04-24 18:27:22.145 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 1 | 6 | CHANGE IfStmt to IfStmt = 1 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 4 | 8 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onReStartState=map.get("onStart"); | 283 | SingleLockState onRestartState=map.get("onStart"); | |
| 284 | if (locking(onStartState)) { | 284 | if (locking(onStartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 310 | SingleLockState onReceiveState=map.get("onReceive"); | 310 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 311 | if (locking(onReceiveState)) { | 311 | if (locking(onReceiveState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_018 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_019 | |||
|---|---|---|---|---|
|
317 lines 12370 bytes Last modified : Mon May 14 23:48:03 2012 |
317 lines 12372 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:22.145 | 1 | //Time : 2012-04-24 18:27:25.426 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 1 | 6 | CHANGE IfStmt to IfStmt = 1 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 4 | 8 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onStart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onStartState)) { | 284 | if (locking(onStartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 310 | SingleLockState onReceiveState=map.get("onReceive"); | 310 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 311 | if (locking(onReceiveState)) { | 311 | if (locking(onReceiveState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_019 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_020 | |||
|---|---|---|---|---|
|
317 lines 12372 bytes Last modified : Mon May 14 23:48:03 2012 |
316 lines 12328 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:25.426 | 1 | //Time : 2012-04-24 18:27:32.177 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE IfStmt to IfStmt = 1 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 4 | 7 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 15 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 17 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 25 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 28 | /** | 27 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 29 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 33 | private Component component; | 32 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 36 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 39 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 41 | return allExitStates; | |
| 43 | } | 42 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 46 | } | 45 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 49 | } | 48 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 52 | } | 51 | } | |
| 53 | public String toString(){ | 52 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 60 | } | |
| 62 | } | 61 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 69 | ; | 68 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 72 | } | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | return null; | 76 | return null; | |
| 78 | } | 77 | } | |
| 79 | } | 78 | } | |
| 80 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 81 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 83 | /** | |
| 85 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 85 | * @param component | |
| 87 | */ | 86 | */ | |
| 88 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 95 | } | |
| 97 | } | 96 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 98 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 100 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 104 | } | 103 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 107 | } | 106 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 109 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 113 | } | 112 | } | |
| 114 | else { | 113 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 115 | } | |
| 117 | } | 116 | } | |
| 118 | else { | 117 | else { | |
| 119 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 120 | } | 119 | } | |
| 121 | } | 120 | } | |
| 122 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 146 | printMethod=true; | |
| 148 | } | 147 | } | |
| 149 | } | 148 | } | |
| 150 | if (printMethod) { | 149 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 151 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 159 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 165 | } | |
| 167 | else { | 166 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 171 | } | 170 | } | |
| 172 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 173 | } | 172 | } | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | if (printComponent) { | 176 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 180 | } | |
| 182 | } | 181 | } | |
| 183 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 188 | } | 187 | } | |
| 189 | } | 188 | } | |
| 190 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 197 | } | 196 | } | |
| 198 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 199 | } | 198 | } | |
| 200 | return result; | 199 | return result; | |
| 201 | } | 200 | } | |
| 202 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 203 | public void output(){ | |
| 205 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 207 | } | 206 | } | |
| 208 | } | 207 | } | |
| 209 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 209 | return this; | |
| 211 | } | 210 | } | |
| 212 | public String toString(){ | 211 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 216 | } | 215 | } | |
| 217 | return result.toString(); | 216 | return result.toString(); | |
| 218 | } | 217 | } | |
| 219 | } | 218 | } | |
| 220 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 221 | private Component component; | 220 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 222 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 226 | } | 225 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 229 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 232 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 234 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 236 | } | |
| 238 | return false; | 237 | return false; | |
| 239 | } | 238 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 240 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 242 | } | |
| 244 | return false; | 243 | return false; | |
| 245 | } | 244 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 248 | } | |
| 250 | return false; | 249 | return false; | |
| 251 | } | 250 | } | |
| 252 | private Logger logger; | 251 | private Logger logger; | |
| 253 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 254 | logger.add(s); | 253 | logger.add(s); | |
| 255 | } | 254 | } | |
| 256 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 257 | return logger; | 256 | return logger; | |
| 258 | } | 257 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 263 | return onStart; | 262 | return onStart; | |
| 264 | } | 263 | } | |
| 265 | else { | 264 | else { | |
| 266 | return onStartCommand; | 265 | return onStartCommand; | |
| 267 | } | 266 | } | |
| 268 | } | 267 | } | |
| 269 | /** | 268 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 270 | */ | |
| 272 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 281 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onStartState)) { | 283 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 290 | } | |
| 292 | } | 291 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 297 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 300 | } | |
| 302 | } | 301 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 306 | } | |
| 308 | } | 307 | } | |
| 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | 308 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 310 | SingleLockState onReceiveState=map.get("onReceive"); | 309 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 311 | if (locking(onReceiveState)) { | 310 | if (locking(onReceiveState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 313 | } | 312 | } | |
| 314 | } | 313 | } | |
| 315 | } | 314 | } | |
| 316 | } | 315 | } | |
| 317 | } | 316 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_020 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_021 | |||
|---|---|---|---|---|
|
316 lines 12328 bytes Last modified : Mon May 14 23:48:03 2012 |
317 lines 12376 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:32.177 | 1 | //Time : 2012-04-24 18:27:37.462 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 5 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 8 | changes = 5 | |
| 8 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 16 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 18 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 26 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 27 | /** | 28 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 30 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 32 | private Component component; | 33 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 37 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 40 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 42 | return allExitStates; | |
| 42 | } | 43 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 45 | } | 46 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 48 | } | 49 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 51 | } | 52 | } | |
| 52 | public String toString(){ | 53 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 61 | } | |
| 61 | } | 62 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 68 | ; | 69 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 73 | } | |
| 73 | } | 74 | } | |
| 74 | } | 75 | } | |
| 75 | } | 76 | } | |
| 76 | return null; | 77 | return null; | |
| 77 | } | 78 | } | |
| 78 | } | 79 | } | |
| 79 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 82 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 84 | /** | |
| 84 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 86 | * @param component | |
| 86 | */ | 87 | */ | |
| 87 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 96 | } | |
| 96 | } | 97 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 99 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 101 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 103 | } | 104 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 106 | } | 107 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 110 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 112 | } | 113 | } | |
| 113 | else { | 114 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 116 | } | |
| 116 | } | 117 | } | |
| 117 | else { | 118 | else { | |
| 118 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 119 | } | 120 | } | |
| 120 | } | 121 | } | |
| 121 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 147 | printMethod=true; | |
| 147 | } | 148 | } | |
| 148 | } | 149 | } | |
| 149 | if (printMethod) { | 150 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 152 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 160 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 166 | } | |
| 166 | else { | 167 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 170 | } | 171 | } | |
| 171 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 172 | } | 173 | } | |
| 173 | } | 174 | } | |
| 174 | } | 175 | } | |
| 175 | } | 176 | } | |
| 176 | if (printComponent) { | 177 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 181 | } | |
| 181 | } | 182 | } | |
| 182 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 187 | } | 188 | } | |
| 188 | } | 189 | } | |
| 189 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 196 | } | 197 | } | |
| 197 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 198 | } | 199 | } | |
| 199 | return result; | 200 | return result; | |
| 200 | } | 201 | } | |
| 201 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 204 | public void output(){ | |
| 204 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 206 | } | 207 | } | |
| 207 | } | 208 | } | |
| 208 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 210 | return this; | |
| 210 | } | 211 | } | |
| 211 | public String toString(){ | 212 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 215 | } | 216 | } | |
| 216 | return result.toString(); | 217 | return result.toString(); | |
| 217 | } | 218 | } | |
| 218 | } | 219 | } | |
| 219 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 220 | private Component component; | 221 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 223 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 225 | } | 226 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 230 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 233 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 235 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 237 | } | |
| 237 | return false; | 238 | return false; | |
| 238 | } | 239 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 241 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 243 | } | |
| 243 | return false; | 244 | return false; | |
| 244 | } | 245 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 249 | } | |
| 249 | return false; | 250 | return false; | |
| 250 | } | 251 | } | |
| 251 | private Logger logger; | 252 | private Logger logger; | |
| 252 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 253 | logger.add(s); | 254 | logger.add(s); | |
| 254 | } | 255 | } | |
| 255 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 256 | return logger; | 257 | return logger; | |
| 257 | } | 258 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 262 | return onStart; | 263 | return onStart; | |
| 263 | } | 264 | } | |
| 264 | else { | 265 | else { | |
| 265 | return onStartCommand; | 266 | return onStartCommand; | |
| 266 | } | 267 | } | |
| 267 | } | 268 | } | |
| 268 | /** | 269 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 271 | */ | |
| 271 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 278 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 282 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 286 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 291 | } | |
| 291 | } | 292 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 298 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 301 | } | |
| 301 | } | 302 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 307 | } | |
| 307 | } | 308 | } | |
| 308 | if (component.getComponentType().equals("BroadcastReceiver")) { | 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 309 | SingleLockState onReceiveState=map.get("onReceive"); | 310 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 310 | if (locking(onReceiveState)) { | 311 | if (locking(onReceiveState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 312 | } | 313 | } | |
| 313 | } | 314 | } | |
| 314 | } | 315 | } | |
| 315 | } | 316 | } | |
| 316 | } | 317 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_021 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_022 | |||
|---|---|---|---|---|
|
317 lines 12376 bytes Last modified : Mon May 14 23:48:03 2012 |
323 lines 12856 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 18:27:37.462 | 1 | //Time : 2012-04-24 19:01:34.462 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 6 | INSERT IfStmt = 1 | |
| 7 | changes = 2 | |||
| 9 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | inserts = 1 | |||
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("RunnableThread")) { | |||
| 310 | SingleLockState runState=map.get("run"); | |||
| 311 | if (locking(runState)) { | |||
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |||
| 313 | } | |||
| 314 | } | |||
| 309 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 310 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 311 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 313 | } | 319 | } | |
| 314 | } | 320 | } | |
| 315 | } | 321 | } | |
| 316 | } | 322 | } | |
| 317 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_022 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_023 | |||
|---|---|---|---|---|
|
323 lines 12856 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12848 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:34.462 | 1 | //Time : 2012-04-24 19:01:41.521 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 1 | |||
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | INSERT IfStmt = 1 | 7 | changes = 3 | |
| 7 | changes = 2 | |||
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | inserts = 1 | |||
| 10 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 15 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 17 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 25 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 28 | /** | 27 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 29 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 33 | private Component component; | 32 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 36 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 39 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 41 | return allExitStates; | |
| 43 | } | 42 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 46 | } | 45 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 49 | } | 48 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 52 | } | 51 | } | |
| 53 | public String toString(){ | 52 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 60 | } | |
| 62 | } | 61 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 69 | ; | 68 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 72 | } | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | return null; | 76 | return null; | |
| 78 | } | 77 | } | |
| 79 | } | 78 | } | |
| 80 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 81 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 83 | /** | |
| 85 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 85 | * @param component | |
| 87 | */ | 86 | */ | |
| 88 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 95 | } | |
| 97 | } | 96 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 98 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 100 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 104 | } | 103 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 107 | } | 106 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 109 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 113 | } | 112 | } | |
| 114 | else { | 113 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 115 | } | |
| 117 | } | 116 | } | |
| 118 | else { | 117 | else { | |
| 119 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 120 | } | 119 | } | |
| 121 | } | 120 | } | |
| 122 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 146 | printMethod=true; | |
| 148 | } | 147 | } | |
| 149 | } | 148 | } | |
| 150 | if (printMethod) { | 149 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 151 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 159 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 165 | } | |
| 167 | else { | 166 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 171 | } | 170 | } | |
| 172 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 173 | } | 172 | } | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | if (printComponent) { | 176 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 180 | } | |
| 182 | } | 181 | } | |
| 183 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 188 | } | 187 | } | |
| 189 | } | 188 | } | |
| 190 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 197 | } | 196 | } | |
| 198 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 199 | } | 198 | } | |
| 200 | return result; | 199 | return result; | |
| 201 | } | 200 | } | |
| 202 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 203 | public void output(){ | |
| 205 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 207 | } | 206 | } | |
| 208 | } | 207 | } | |
| 209 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 209 | return this; | |
| 211 | } | 210 | } | |
| 212 | public String toString(){ | 211 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 216 | } | 215 | } | |
| 217 | return result.toString(); | 216 | return result.toString(); | |
| 218 | } | 217 | } | |
| 219 | } | 218 | } | |
| 220 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 221 | private Component component; | 220 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 222 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 226 | } | 225 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 229 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 232 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 234 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 236 | } | |
| 238 | return false; | 237 | return false; | |
| 239 | } | 238 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 240 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 242 | } | |
| 244 | return false; | 243 | return false; | |
| 245 | } | 244 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 248 | } | |
| 250 | return false; | 249 | return false; | |
| 251 | } | 250 | } | |
| 252 | private Logger logger; | 251 | private Logger logger; | |
| 253 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 254 | logger.add(s); | 253 | logger.add(s); | |
| 255 | } | 254 | } | |
| 256 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 257 | return logger; | 256 | return logger; | |
| 258 | } | 257 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 263 | return onStart; | 262 | return onStart; | |
| 264 | } | 263 | } | |
| 265 | else { | 264 | else { | |
| 266 | return onStartCommand; | 265 | return onStartCommand; | |
| 267 | } | 266 | } | |
| 268 | } | 267 | } | |
| 269 | /** | 268 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 270 | */ | |
| 272 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 281 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 290 | } | |
| 292 | } | 291 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 297 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 300 | } | |
| 302 | } | 301 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 306 | } | |
| 308 | } | 307 | } | |
| 309 | if (component.getComponentType().equals("RunnableThread")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState runState=map.get("run"); | 309 | SingleLockState runState=map.get("run"); | |
| 311 | if (locking(runState)) { | 310 | if (locking(runState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 313 | } | 312 | } | |
| 314 | } | 313 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 318 | } | |
| 320 | } | 319 | } | |
| 321 | } | 320 | } | |
| 322 | } | 321 | } | |
| 323 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_023 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_024 | |||
|---|---|---|---|---|
|
322 lines 12848 bytes Last modified : Mon May 14 23:48:03 2012 |
323 lines 12897 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:41.521 | 1 | //Time : 2012-04-24 19:01:44.800 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 5 | CHANGE IfStmt to IfStmt = 1 | 6 | CHANGE IfStmt to IfStmt = 1 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 3 | 8 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 16 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 18 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 26 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 27 | /** | 28 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 30 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 32 | private Component component; | 33 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 37 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 40 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 42 | return allExitStates; | |
| 42 | } | 43 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 45 | } | 46 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 48 | } | 49 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 51 | } | 52 | } | |
| 52 | public String toString(){ | 53 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 61 | } | |
| 61 | } | 62 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 68 | ; | 69 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 73 | } | |
| 73 | } | 74 | } | |
| 74 | } | 75 | } | |
| 75 | } | 76 | } | |
| 76 | return null; | 77 | return null; | |
| 77 | } | 78 | } | |
| 78 | } | 79 | } | |
| 79 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 82 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 84 | /** | |
| 84 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 86 | * @param component | |
| 86 | */ | 87 | */ | |
| 87 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 96 | } | |
| 96 | } | 97 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 99 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 101 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 103 | } | 104 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 106 | } | 107 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 110 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 112 | } | 113 | } | |
| 113 | else { | 114 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 116 | } | |
| 116 | } | 117 | } | |
| 117 | else { | 118 | else { | |
| 118 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 119 | } | 120 | } | |
| 120 | } | 121 | } | |
| 121 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 147 | printMethod=true; | |
| 147 | } | 148 | } | |
| 148 | } | 149 | } | |
| 149 | if (printMethod) { | 150 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 152 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 160 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 166 | } | |
| 166 | else { | 167 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 170 | } | 171 | } | |
| 171 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 172 | } | 173 | } | |
| 173 | } | 174 | } | |
| 174 | } | 175 | } | |
| 175 | } | 176 | } | |
| 176 | if (printComponent) { | 177 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 181 | } | |
| 181 | } | 182 | } | |
| 182 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 187 | } | 188 | } | |
| 188 | } | 189 | } | |
| 189 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 196 | } | 197 | } | |
| 197 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 198 | } | 199 | } | |
| 199 | return result; | 200 | return result; | |
| 200 | } | 201 | } | |
| 201 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 204 | public void output(){ | |
| 204 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 206 | } | 207 | } | |
| 207 | } | 208 | } | |
| 208 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 210 | return this; | |
| 210 | } | 211 | } | |
| 211 | public String toString(){ | 212 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 215 | } | 216 | } | |
| 216 | return result.toString(); | 217 | return result.toString(); | |
| 217 | } | 218 | } | |
| 218 | } | 219 | } | |
| 219 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 220 | private Component component; | 221 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 223 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 225 | } | 226 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 230 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 233 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 235 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 237 | } | |
| 237 | return false; | 238 | return false; | |
| 238 | } | 239 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 241 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 243 | } | |
| 243 | return false; | 244 | return false; | |
| 244 | } | 245 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 249 | } | |
| 249 | return false; | 250 | return false; | |
| 250 | } | 251 | } | |
| 251 | private Logger logger; | 252 | private Logger logger; | |
| 252 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 253 | logger.add(s); | 254 | logger.add(s); | |
| 254 | } | 255 | } | |
| 255 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 256 | return logger; | 257 | return logger; | |
| 257 | } | 258 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 262 | return onStart; | 263 | return onStart; | |
| 263 | } | 264 | } | |
| 264 | else { | 265 | else { | |
| 265 | return onStartCommand; | 266 | return onStartCommand; | |
| 266 | } | 267 | } | |
| 267 | } | 268 | } | |
| 268 | /** | 269 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 271 | */ | |
| 271 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 278 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 282 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 286 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 291 | } | |
| 291 | } | 292 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 298 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 301 | } | |
| 301 | } | 302 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 307 | } | |
| 307 | } | 308 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("run"); | 310 | SingleLockState runState=map.get("handle"); | |
| 310 | if (locking(runState)) { | 311 | if (locking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 313 | } | |
| 313 | } | 314 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 319 | } | |
| 319 | } | 320 | } | |
| 320 | } | 321 | } | |
| 321 | } | 322 | } | |
| 322 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_024 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_025 | |||
|---|---|---|---|---|
|
323 lines 12897 bytes Last modified : Mon May 14 23:48:03 2012 |
323 lines 12904 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:44.800 | 1 | //Time : 2012-04-24 19:01:48.592 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 1 | 6 | CHANGE IfStmt to IfStmt = 1 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 4 | 8 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState runState=map.get("handle"); | 310 | SingleLockState runState=map.get("handleMessage"); | |
| 311 | if (locking(runState)) { | 311 | if (locking(runState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_025 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_026 | |||
|---|---|---|---|---|
|
323 lines 12904 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12859 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:01:48.592 | 1 | //Time : 2012-04-24 19:02:05.916 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE IfStmt to IfStmt = 1 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 4 | 7 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 15 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 17 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 25 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 28 | /** | 27 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 29 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 33 | private Component component; | 32 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 36 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 39 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 41 | return allExitStates; | |
| 43 | } | 42 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 46 | } | 45 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 49 | } | 48 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 52 | } | 51 | } | |
| 53 | public String toString(){ | 52 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 60 | } | |
| 62 | } | 61 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 69 | ; | 68 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 72 | } | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | return null; | 76 | return null; | |
| 78 | } | 77 | } | |
| 79 | } | 78 | } | |
| 80 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 81 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 83 | /** | |
| 85 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 85 | * @param component | |
| 87 | */ | 86 | */ | |
| 88 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 95 | } | |
| 97 | } | 96 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 98 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 100 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 104 | } | 103 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 107 | } | 106 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 109 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 113 | } | 112 | } | |
| 114 | else { | 113 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 115 | } | |
| 117 | } | 116 | } | |
| 118 | else { | 117 | else { | |
| 119 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 120 | } | 119 | } | |
| 121 | } | 120 | } | |
| 122 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 146 | printMethod=true; | |
| 148 | } | 147 | } | |
| 149 | } | 148 | } | |
| 150 | if (printMethod) { | 149 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 151 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 159 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 165 | } | |
| 167 | else { | 166 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 171 | } | 170 | } | |
| 172 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 173 | } | 172 | } | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | if (printComponent) { | 176 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 180 | } | |
| 182 | } | 181 | } | |
| 183 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 188 | } | 187 | } | |
| 189 | } | 188 | } | |
| 190 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 197 | } | 196 | } | |
| 198 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 199 | } | 198 | } | |
| 200 | return result; | 199 | return result; | |
| 201 | } | 200 | } | |
| 202 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 203 | public void output(){ | |
| 205 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 207 | } | 206 | } | |
| 208 | } | 207 | } | |
| 209 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 209 | return this; | |
| 211 | } | 210 | } | |
| 212 | public String toString(){ | 211 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 216 | } | 215 | } | |
| 217 | return result.toString(); | 216 | return result.toString(); | |
| 218 | } | 217 | } | |
| 219 | } | 218 | } | |
| 220 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 221 | private Component component; | 220 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 222 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 226 | } | 225 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 229 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 232 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 234 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 236 | } | |
| 238 | return false; | 237 | return false; | |
| 239 | } | 238 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 240 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 242 | } | |
| 244 | return false; | 243 | return false; | |
| 245 | } | 244 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 248 | } | |
| 250 | return false; | 249 | return false; | |
| 251 | } | 250 | } | |
| 252 | private Logger logger; | 251 | private Logger logger; | |
| 253 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 254 | logger.add(s); | 253 | logger.add(s); | |
| 255 | } | 254 | } | |
| 256 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 257 | return logger; | 256 | return logger; | |
| 258 | } | 257 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 263 | return onStart; | 262 | return onStart; | |
| 264 | } | 263 | } | |
| 265 | else { | 264 | else { | |
| 266 | return onStartCommand; | 265 | return onStartCommand; | |
| 267 | } | 266 | } | |
| 268 | } | 267 | } | |
| 269 | /** | 268 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 270 | */ | |
| 272 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 281 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 290 | } | |
| 292 | } | 291 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 297 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 300 | } | |
| 302 | } | 301 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 306 | } | |
| 308 | } | 307 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 311 | if (locking(runState)) { | 310 | if (flocking(runState)) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 313 | } | 312 | } | |
| 314 | } | 313 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 318 | } | |
| 320 | } | 319 | } | |
| 321 | } | 320 | } | |
| 322 | } | 321 | } | |
| 323 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_026 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_027 | |||
|---|---|---|---|---|
|
322 lines 12859 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12862 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:05.916 | 1 | //Time : 2012-04-24 19:02:08.262 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (flocking(runState)) { | 310 | if (fulllocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_027 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_028 | |||
|---|---|---|---|---|
|
322 lines 12862 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12858 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:08.262 | 1 | //Time : 2012-04-24 19:02:10.551 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (fulllocking(runState)) { | 310 | if (locking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_028 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_029 | |||
|---|---|---|---|---|
|
322 lines 12858 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12860 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:10.551 | 1 | //Time : 2012-04-24 19:02:12.861 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (locking(runState)) { | 310 | if (unlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_029 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_030 | |||
|---|---|---|---|---|
|
322 lines 12860 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12867 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:12.861 | 1 | //Time : 2012-04-24 19:02:19.167 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (unlocking(runState)) { | 310 | if (stroingunlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_030 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_031 | |||
|---|---|---|---|---|
|
322 lines 12867 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12868 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:19.167 | 1 | //Time : 2012-04-24 19:02:20.513 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (stroingunlocking(runState)) { | 310 | if (!stroingunlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_031 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_032 | |||
|---|---|---|---|---|
|
322 lines 12868 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12867 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:20.513 | 1 | //Time : 2012-04-24 19:02:22.285 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (!stroingunlocking(runState)) { | 310 | if (!strongunlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_032 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_033 | |||
|---|---|---|---|---|
|
322 lines 12867 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12866 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:22.285 | 1 | //Time : 2012-04-24 19:02:23.556 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (!strongunlocking(runState)) { | 310 | if (!strongnlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_033 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_034 | |||
|---|---|---|---|---|
|
322 lines 12866 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12877 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:23.556 | 1 | //Time : 2012-04-24 19:02:26.816 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (!strongnlocking(runState)) { | 310 | if (!strongUnlocking(state) * (runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_034 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_035 | |||
|---|---|---|---|---|
|
322 lines 12877 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12867 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:26.816 | 1 | //Time : 2012-04-24 19:02:29.611 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (!strongUnlocking(state) * (runState)) { | 310 | if (!strongUnlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_035 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_036 | |||
|---|---|---|---|---|
|
322 lines 12867 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12886 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:29.611 | 1 | //Time : 2012-04-24 19:02:34.974 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (!strongUnlocking(runState)) { | 310 | if (unlocking(state) != strongUnlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_036 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_037 | |||
|---|---|---|---|---|
|
322 lines 12886 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12889 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:34.974 | 1 | //Time : 2012-04-24 19:02:38.238 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (unlocking(state) != strongUnlocking(runState)) { | 310 | if (unlocking(runState) != strongUnlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_037 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_038 | |||
|---|---|---|---|---|
|
322 lines 12889 bytes Last modified : Mon May 14 23:48:03 2012 |
337 lines 13103 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:38.238 | 1 | //Time : 2012-04-24 19:02:41.064 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | ERROR: Encountered " "void" "void "" at line 303, column 37. | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | Was expecting one of: | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | "false" ... | |
| 7 | changes = 4 | 7 | "new" ... | |
| 8 | changes to method solveFacts = 1 | 8 | "null" ... | |
| 9 | private/protected method declarations = 1 | 9 | "super" ... | |
| 10 | "this" ... | |||
| 11 | "true" ... | |||
| 12 | <LONG_LITERAL> ... | |||
| 13 | <INTEGER_LITERAL> ... | |||
| 14 | <FLOATING_POINT_LITERAL> ... | |||
| 15 | <CHARACTER_LITERAL> ... | |||
| 16 | <STRING_LITERAL> ... | |||
| 17 | <IDENTIFIER> ... | |||
| 18 | "(" ... | |||
| 19 | "!" ... | |||
| 20 | "~" ... | |||
| 21 | <IDENTIFIER> ... | |||
| 22 | "(" ... | |||
| 23 | ||||
| 24 | [Ljava.lang.StackTraceElement;@2206179e = 1 | |||
| 10 | */package energy.analysis; | 25 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 26 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 27 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 28 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 29 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 30 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 31 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 32 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 33 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 34 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 36 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 37 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 38 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 39 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 40 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 41 | public class AnalysisResults { | |
| 27 | /** | 42 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 43 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 44 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 45 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 46 | public class ComponentSummary { | |
| 32 | private Component component; | 47 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 48 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 49 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 50 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 51 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 52 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 53 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 54 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 55 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 56 | return allExitStates; | |
| 42 | } | 57 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 58 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 59 | allExitStates.put(n,st); | |
| 45 | } | 60 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 61 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 62 | callBackExitStates.put(cb,st); | |
| 48 | } | 63 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 64 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 65 | return allExitStates.get(method); | |
| 51 | } | 66 | } | |
| 52 | public String toString(){ | 67 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 68 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 69 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 70 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 71 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 72 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 73 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 74 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 75 | } | |
| 61 | } | 76 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 77 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 78 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 79 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 80 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 81 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 82 | String name=cb.getName(); | |
| 68 | ; | 83 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 84 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 85 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 86 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 87 | } | |
| 73 | } | 88 | } | |
| 74 | } | 89 | } | |
| 75 | } | 90 | } | |
| 76 | return null; | 91 | return null; | |
| 77 | } | 92 | } | |
| 78 | } | 93 | } | |
| 79 | public AnalysisResults(){ | 94 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 95 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 96 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 97 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 98 | /** | |
| 84 | * Invoke this after the component has been analyzed | 99 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 100 | * @param component | |
| 86 | */ | 101 | */ | |
| 87 | public void createComponentSummary( Component component){ | 102 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 103 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 104 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 105 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 106 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 107 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 108 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 109 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 110 | } | |
| 96 | } | 111 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 112 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 113 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 114 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 115 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 116 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 117 | return LockUsage.LOCKING; | |
| 103 | } | 118 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 119 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 120 | return LockUsage.EMPTY; | |
| 106 | } | 121 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 122 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 123 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 124 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 125 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 126 | return LockUsage.UNLOCKING; | |
| 112 | } | 127 | } | |
| 113 | else { | 128 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 129 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 130 | } | |
| 116 | } | 131 | } | |
| 117 | else { | 132 | else { | |
| 118 | return LockUsage.EMPTY; | 133 | return LockUsage.EMPTY; | |
| 119 | } | 134 | } | |
| 120 | } | 135 | } | |
| 121 | public ArrayList<String> processResults(){ | 136 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 137 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 138 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 139 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 140 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 141 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 142 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 143 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 144 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 145 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 146 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 147 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 148 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 149 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 150 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 151 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 152 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 153 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 155 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 156 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 157 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 158 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 159 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 160 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 161 | printMethod=true; | |
| 147 | } | 162 | } | |
| 148 | } | 163 | } | |
| 149 | if (printMethod) { | 164 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 165 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 166 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 167 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 168 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 169 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 170 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 171 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 172 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 173 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 174 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 175 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 176 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 177 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 178 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 179 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 180 | } | |
| 166 | else { | 181 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 182 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 183 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 184 | usageMap.put(lu,set); | |
| 170 | } | 185 | } | |
| 171 | policy.addFact(node,mergedLS); | 186 | policy.addFact(node,mergedLS); | |
| 172 | } | 187 | } | |
| 173 | } | 188 | } | |
| 174 | } | 189 | } | |
| 175 | } | 190 | } | |
| 176 | if (printComponent) { | 191 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 192 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 193 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 194 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 195 | } | |
| 181 | } | 196 | } | |
| 182 | System.out.println("==========================================\n"); | 197 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 198 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 199 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 200 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 201 | System.out.println(" " + s.toString()); | |
| 187 | } | 202 | } | |
| 188 | } | 203 | } | |
| 189 | System.out.println("==========================================\n"); | 204 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 205 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 206 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 207 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 208 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 209 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 210 | System.out.println("\n"); | |
| 196 | } | 211 | } | |
| 197 | result=logger.getStringList(); | 212 | result=logger.getStringList(); | |
| 198 | } | 213 | } | |
| 199 | return result; | 214 | return result; | |
| 200 | } | 215 | } | |
| 201 | public class Logger extends ArrayList<String> { | 216 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 217 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 218 | public void output(){ | |
| 204 | for ( String s : this) { | 219 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 220 | System.out.println(" " + s); | |
| 206 | } | 221 | } | |
| 207 | } | 222 | } | |
| 208 | public ArrayList<String> getStringList(){ | 223 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 224 | return this; | |
| 210 | } | 225 | } | |
| 211 | public String toString(){ | 226 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 227 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 228 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 229 | result.append(s + "\n"); | |
| 215 | } | 230 | } | |
| 216 | return result.toString(); | 231 | return result.toString(); | |
| 217 | } | 232 | } | |
| 218 | } | 233 | } | |
| 219 | public class ComponentPolicy { | 234 | public class ComponentPolicy { | |
| 220 | private Component component; | 235 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 236 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 237 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 238 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 239 | logger=new Logger(); | |
| 225 | } | 240 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 241 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 242 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 243 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 244 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 245 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 246 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 247 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 248 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 249 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 250 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 251 | } | |
| 237 | return false; | 252 | return false; | |
| 238 | } | 253 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 254 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 255 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 256 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 257 | } | |
| 243 | return false; | 258 | return false; | |
| 244 | } | 259 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 260 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 261 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 262 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 263 | } | |
| 249 | return false; | 264 | return false; | |
| 250 | } | 265 | } | |
| 251 | private Logger logger; | 266 | private Logger logger; | |
| 252 | private void logNote( String s){ | 267 | private void logNote( String s){ | |
| 253 | logger.add(s); | 268 | logger.add(s); | |
| 254 | } | 269 | } | |
| 255 | public Logger getLogger(){ | 270 | public Logger getLogger(){ | |
| 256 | return logger; | 271 | return logger; | |
| 257 | } | 272 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 273 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 274 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 275 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 276 | if (onStartCommand == null) { | |
| 262 | return onStart; | 277 | return onStart; | |
| 263 | } | 278 | } | |
| 264 | else { | 279 | else { | |
| 265 | return onStartCommand; | 280 | return onStartCommand; | |
| 266 | } | 281 | } | |
| 267 | } | 282 | } | |
| 268 | /** | 283 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 284 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 285 | */ | |
| 271 | public void solveFacts(){ | 286 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 287 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 288 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 289 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 290 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 291 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 292 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 293 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 294 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 295 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 296 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 297 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 298 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 299 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 300 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 301 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 302 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 303 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 304 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 305 | } | |
| 291 | } | 306 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 307 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 308 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 309 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 310 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 311 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 312 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 313 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 314 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 315 | } | |
| 301 | } | 316 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 317 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 318 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 319 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 321 | } | |
| 307 | } | 322 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 323 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 324 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (unlocking(runState) != strongUnlocking(runState)) { | 325 | if (unlocking(runState) && (void)!strongUnlocking(runState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 326 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 327 | } | |
| 313 | } | 328 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 329 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 330 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 331 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 332 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 333 | } | |
| 319 | } | 334 | } | |
| 320 | } | 335 | } | |
| 321 | } | 336 | } | |
| 322 | } | 337 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_038 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_039 | |||
|---|---|---|---|---|
|
337 lines 13103 bytes Last modified : Mon May 14 23:48:03 2012 |
337 lines 13098 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:41.064 | 1 | //Time : 2012-04-24 19:02:43.406 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | ERROR: Encountered " "void" "void "" at line 303, column 37. | 4 | ERROR: Encountered " "void" "void "" at line 325, column 37. | |
| 5 | Was expecting one of: | 5 | Was expecting one of: | |
| 6 | "false" ... | 6 | "false" ... | |
| 7 | "new" ... | 7 | "new" ... | |
| 8 | "null" ... | 8 | "null" ... | |
| 9 | "super" ... | 9 | "super" ... | |
| 10 | "this" ... | 10 | "this" ... | |
| 11 | "true" ... | 11 | "true" ... | |
| 12 | <LONG_LITERAL> ... | 12 | <LONG_LITERAL> ... | |
| 13 | <INTEGER_LITERAL> ... | 13 | <INTEGER_LITERAL> ... | |
| 14 | <FLOATING_POINT_LITERAL> ... | 14 | <FLOATING_POINT_LITERAL> ... | |
| 15 | <CHARACTER_LITERAL> ... | 15 | <CHARACTER_LITERAL> ... | |
| 16 | <STRING_LITERAL> ... | 16 | <STRING_LITERAL> ... | |
| 17 | <IDENTIFIER> ... | 17 | <IDENTIFIER> ... | |
| 18 | "(" ... | 18 | "(" ... | |
| 19 | "!" ... | 19 | "!" ... | |
| 20 | "~" ... | 20 | "~" ... | |
| 21 | <IDENTIFIER> ... | 21 | <IDENTIFIER> ... | |
| 22 | "(" ... | 22 | "(" ... | |
| 23 | 23 | |||
| 24 | [Ljava.lang.StackTraceElement;@2206179e = 1 | 24 | [Ljava.lang.StackTraceElement;@ba3bc8c = 1 | |
| 25 | */package energy.analysis; | 25 | */package energy.analysis; | |
| 26 | import java.util.ArrayList; | 26 | import java.util.ArrayList; | |
| 27 | import java.util.HashMap; | 27 | import java.util.HashMap; | |
| 28 | import java.util.HashSet; | 28 | import java.util.HashSet; | |
| 29 | import java.util.Iterator; | 29 | import java.util.Iterator; | |
| 30 | import java.util.Map; | 30 | import java.util.Map; | |
| 31 | import java.util.Map.Entry; | 31 | import java.util.Map.Entry; | |
| 32 | import java.util.Set; | 32 | import java.util.Set; | |
| 33 | import com.ibm.wala.ipa.callgraph.CGNode; | 33 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 34 | import com.ibm.wala.util.collections.Pair; | 34 | import com.ibm.wala.util.collections.Pair; | |
| 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 36 | import energy.components.Component; | 36 | import energy.components.Component; | |
| 37 | import energy.components.Component.CallBack; | 37 | import energy.components.Component.CallBack; | |
| 38 | import energy.interproc.CompoundLockState; | 38 | import energy.interproc.CompoundLockState; | |
| 39 | import energy.interproc.SingleLockState; | 39 | import energy.interproc.SingleLockState; | |
| 40 | import energy.util.E; | 40 | import energy.util.E; | |
| 41 | public class AnalysisResults { | 41 | public class AnalysisResults { | |
| 42 | /** | 42 | /** | |
| 43 | * Main structures that hold the analysis results for every component | 43 | * Main structures that hold the analysis results for every component | |
| 44 | */ | 44 | */ | |
| 45 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 45 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 46 | public class ComponentSummary { | 46 | public class ComponentSummary { | |
| 47 | private Component component; | 47 | private Component component; | |
| 48 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 48 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 49 | private HashMap<CGNode,CompoundLockState> allExitStates; | 49 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 50 | public ComponentSummary( Component c){ | 50 | public ComponentSummary( Component c){ | |
| 51 | this.component=c; | 51 | this.component=c; | |
| 52 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 52 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 53 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 53 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 54 | } | 54 | } | |
| 55 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 55 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 56 | return allExitStates; | 56 | return allExitStates; | |
| 57 | } | 57 | } | |
| 58 | public void registerNodeState( CGNode n, CompoundLockState st){ | 58 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 59 | allExitStates.put(n,st); | 59 | allExitStates.put(n,st); | |
| 60 | } | 60 | } | |
| 61 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 61 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 62 | callBackExitStates.put(cb,st); | 62 | callBackExitStates.put(cb,st); | |
| 63 | } | 63 | } | |
| 64 | public CompoundLockState getStateForMethod( String method){ | 64 | public CompoundLockState getStateForMethod( String method){ | |
| 65 | return allExitStates.get(method); | 65 | return allExitStates.get(method); | |
| 66 | } | 66 | } | |
| 67 | public String toString(){ | 67 | public String toString(){ | |
| 68 | StringBuffer sb=new StringBuffer(); | 68 | StringBuffer sb=new StringBuffer(); | |
| 69 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 69 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 70 | CGNode next=it.next(); | 70 | CGNode next=it.next(); | |
| 71 | String name=next.getMethod().getName().toString(); | 71 | String name=next.getMethod().getName().toString(); | |
| 72 | CompoundLockState stateForMethod=getStateForMethod(name); | 72 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 73 | if (stateForMethod != null) { | 73 | if (stateForMethod != null) { | |
| 74 | sb.append(name + ":\n" + stateForMethod.toString()); | 74 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | HashSet<CallBack> callbacks=component.getCallbacks(); | 77 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 78 | if (callbacks != null) { | 78 | if (callbacks != null) { | |
| 79 | if (callbacks.size() > 0) { | 79 | if (callbacks.size() > 0) { | |
| 80 | sb.append("Callbacks:\n"); | 80 | sb.append("Callbacks:\n"); | |
| 81 | for ( CallBack cb : callbacks) { | 81 | for ( CallBack cb : callbacks) { | |
| 82 | String name=cb.getName(); | 82 | String name=cb.getName(); | |
| 83 | ; | 83 | ; | |
| 84 | CompoundLockState stateForMethod=getStateForMethod(name); | 84 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 85 | if (stateForMethod != null) { | 85 | if (stateForMethod != null) { | |
| 86 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 86 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 87 | } | 87 | } | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | } | 90 | } | |
| 91 | return null; | 91 | return null; | |
| 92 | } | 92 | } | |
| 93 | } | 93 | } | |
| 94 | public AnalysisResults(){ | 94 | public AnalysisResults(){ | |
| 95 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 95 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 96 | } | 96 | } | |
| 97 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 97 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 98 | /** | 98 | /** | |
| 99 | * Invoke this after the component has been analyzed | 99 | * Invoke this after the component has been analyzed | |
| 100 | * @param component | 100 | * @param component | |
| 101 | */ | 101 | */ | |
| 102 | public void createComponentSummary( Component component){ | 102 | public void createComponentSummary( Component component){ | |
| 103 | ComponentSummary componentSummary=new ComponentSummary(component); | 103 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 104 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 104 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 105 | CGNode next=it.next(); | 105 | CGNode next=it.next(); | |
| 106 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 106 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 107 | if (exitState != null) { | 107 | if (exitState != null) { | |
| 108 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 108 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 109 | componentSummary.registerNodeState(next,compoundLockState); | 109 | componentSummary.registerNodeState(next,compoundLockState); | |
| 110 | } | 110 | } | |
| 111 | } | 111 | } | |
| 112 | allStates.add(Pair.make(component,componentSummary)); | 112 | allStates.add(Pair.make(component,componentSummary)); | |
| 113 | } | 113 | } | |
| 114 | private LockUsage getLockUsage( SingleLockState runState){ | 114 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 115 | if (runState != null) { | 115 | if (runState != null) { | |
| 116 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 116 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 117 | return LockUsage.LOCKING; | 117 | return LockUsage.LOCKING; | |
| 118 | } | 118 | } | |
| 119 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 119 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 120 | return LockUsage.EMPTY; | 120 | return LockUsage.EMPTY; | |
| 121 | } | 121 | } | |
| 122 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 122 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 123 | return LockUsage.FULL_UNLOCKING; | 123 | return LockUsage.FULL_UNLOCKING; | |
| 124 | } | 124 | } | |
| 125 | else if (runState.isMaybeReleased()) { | 125 | else if (runState.isMaybeReleased()) { | |
| 126 | return LockUsage.UNLOCKING; | 126 | return LockUsage.UNLOCKING; | |
| 127 | } | 127 | } | |
| 128 | else { | 128 | else { | |
| 129 | return LockUsage.UNKNOWN_STATE; | 129 | return LockUsage.UNKNOWN_STATE; | |
| 130 | } | 130 | } | |
| 131 | } | 131 | } | |
| 132 | else { | 132 | else { | |
| 133 | return LockUsage.EMPTY; | 133 | return LockUsage.EMPTY; | |
| 134 | } | 134 | } | |
| 135 | } | 135 | } | |
| 136 | public ArrayList<String> processResults(){ | 136 | public ArrayList<String> processResults(){ | |
| 137 | ArrayList<String> result=null; | 137 | ArrayList<String> result=null; | |
| 138 | System.out.println("\n=========================================="); | 138 | System.out.println("\n=========================================="); | |
| 139 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 139 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 140 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 140 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 141 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 141 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 142 | Component component=pair.fst; | 142 | Component component=pair.fst; | |
| 143 | ComponentSummary cSummary=pair.snd; | 143 | ComponentSummary cSummary=pair.snd; | |
| 144 | ComponentPolicy policy=new ComponentPolicy(component); | 144 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 145 | StringBuffer sb=new StringBuffer(); | 145 | StringBuffer sb=new StringBuffer(); | |
| 146 | boolean printComponent=false; | 146 | boolean printComponent=false; | |
| 147 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 147 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 148 | CGNode node=e.getKey(); | 148 | CGNode node=e.getKey(); | |
| 149 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 149 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 150 | boolean printMethod=false; | 150 | boolean printMethod=false; | |
| 151 | LockUsage lockUsage=LockUsage.EMPTY; | 151 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 152 | CompoundLockState compLS=e.getValue(); | 152 | CompoundLockState compLS=e.getValue(); | |
| 153 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 153 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 155 | WakeLockInstance wli=fs.getKey(); | 155 | WakeLockInstance wli=fs.getKey(); | |
| 156 | Set<SingleLockState> sls=fs.getValue(); | 156 | Set<SingleLockState> sls=fs.getValue(); | |
| 157 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 157 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 158 | lockUsage=getLockUsage(sl); | 158 | lockUsage=getLockUsage(sl); | |
| 159 | lockUsages.put(wli,lockUsage); | 159 | lockUsages.put(wli,lockUsage); | |
| 160 | if (lockUsage != LockUsage.EMPTY) { | 160 | if (lockUsage != LockUsage.EMPTY) { | |
| 161 | printMethod=true; | 161 | printMethod=true; | |
| 162 | } | 162 | } | |
| 163 | } | 163 | } | |
| 164 | if (printMethod) { | 164 | if (printMethod) { | |
| 165 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 165 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 166 | printComponent=true; | 166 | printComponent=true; | |
| 167 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 167 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 168 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 168 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 169 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 169 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 170 | WakeLockInstance key=fs.getKey(); | 170 | WakeLockInstance key=fs.getKey(); | |
| 171 | Set<SingleLockState> value=fs.getValue(); | 171 | Set<SingleLockState> value=fs.getValue(); | |
| 172 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 172 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 173 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 173 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 174 | } | 174 | } | |
| 175 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 175 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 176 | LockUsage lu=getLockUsage(mergedLS); | 176 | LockUsage lu=getLockUsage(mergedLS); | |
| 177 | if (component.isCallBack(node)) { | 177 | if (component.isCallBack(node)) { | |
| 178 | if (usageMap.containsKey(lu)) { | 178 | if (usageMap.containsKey(lu)) { | |
| 179 | usageMap.get(lu).add(Pair.make(component,node)); | 179 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 180 | } | 180 | } | |
| 181 | else { | 181 | else { | |
| 182 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 182 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 183 | set.add(Pair.make(component,node)); | 183 | set.add(Pair.make(component,node)); | |
| 184 | usageMap.put(lu,set); | 184 | usageMap.put(lu,set); | |
| 185 | } | 185 | } | |
| 186 | policy.addFact(node,mergedLS); | 186 | policy.addFact(node,mergedLS); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | } | 190 | } | |
| 191 | if (printComponent) { | 191 | if (printComponent) { | |
| 192 | System.out.println(component.toString() + "\n" + sb.toString()); | 192 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 193 | policy.solveFacts(); | 193 | policy.solveFacts(); | |
| 194 | componentMap.put(component,policy.getLogger()); | 194 | componentMap.put(component,policy.getLogger()); | |
| 195 | } | 195 | } | |
| 196 | } | 196 | } | |
| 197 | System.out.println("==========================================\n"); | 197 | System.out.println("==========================================\n"); | |
| 198 | for ( LockUsage e : usageMap.keySet()) { | 198 | for ( LockUsage e : usageMap.keySet()) { | |
| 199 | System.out.println(e.toString()); | 199 | System.out.println(e.toString()); | |
| 200 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 200 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 201 | System.out.println(" " + s.toString()); | 201 | System.out.println(" " + s.toString()); | |
| 202 | } | 202 | } | |
| 203 | } | 203 | } | |
| 204 | System.out.println("==========================================\n"); | 204 | System.out.println("==========================================\n"); | |
| 205 | for ( Component e : componentMap.keySet()) { | 205 | for ( Component e : componentMap.keySet()) { | |
| 206 | Logger logger=componentMap.get(e); | 206 | Logger logger=componentMap.get(e); | |
| 207 | if (!logger.isEmpty()) { | 207 | if (!logger.isEmpty()) { | |
| 208 | System.out.println(e.toString()); | 208 | System.out.println(e.toString()); | |
| 209 | System.out.println(logger.toString()); | 209 | System.out.println(logger.toString()); | |
| 210 | System.out.println("\n"); | 210 | System.out.println("\n"); | |
| 211 | } | 211 | } | |
| 212 | result=logger.getStringList(); | 212 | result=logger.getStringList(); | |
| 213 | } | 213 | } | |
| 214 | return result; | 214 | return result; | |
| 215 | } | 215 | } | |
| 216 | public class Logger extends ArrayList<String> { | 216 | public class Logger extends ArrayList<String> { | |
| 217 | private static final long serialVersionUID=4402714524487791090L; | 217 | private static final long serialVersionUID=4402714524487791090L; | |
| 218 | public void output(){ | 218 | public void output(){ | |
| 219 | for ( String s : this) { | 219 | for ( String s : this) { | |
| 220 | System.out.println(" " + s); | 220 | System.out.println(" " + s); | |
| 221 | } | 221 | } | |
| 222 | } | 222 | } | |
| 223 | public ArrayList<String> getStringList(){ | 223 | public ArrayList<String> getStringList(){ | |
| 224 | return this; | 224 | return this; | |
| 225 | } | 225 | } | |
| 226 | public String toString(){ | 226 | public String toString(){ | |
| 227 | StringBuffer result=new StringBuffer(); | 227 | StringBuffer result=new StringBuffer(); | |
| 228 | for ( String s : this) { | 228 | for ( String s : this) { | |
| 229 | result.append(s + "\n"); | 229 | result.append(s + "\n"); | |
| 230 | } | 230 | } | |
| 231 | return result.toString(); | 231 | return result.toString(); | |
| 232 | } | 232 | } | |
| 233 | } | 233 | } | |
| 234 | public class ComponentPolicy { | 234 | public class ComponentPolicy { | |
| 235 | private Component component; | 235 | private Component component; | |
| 236 | public ComponentPolicy( Component component){ | 236 | public ComponentPolicy( Component component){ | |
| 237 | this.component=component; | 237 | this.component=component; | |
| 238 | map=new HashMap<String,SingleLockState>(); | 238 | map=new HashMap<String,SingleLockState>(); | |
| 239 | logger=new Logger(); | 239 | logger=new Logger(); | |
| 240 | } | 240 | } | |
| 241 | private HashMap<String,SingleLockState> map; | 241 | private HashMap<String,SingleLockState> map; | |
| 242 | public void addFact( CGNode n, SingleLockState st){ | 242 | public void addFact( CGNode n, SingleLockState st){ | |
| 243 | map.put(n.getMethod().getName().toString(),st); | 243 | map.put(n.getMethod().getName().toString(),st); | |
| 244 | } | 244 | } | |
| 245 | private boolean unlocking( SingleLockState state){ | 245 | private boolean unlocking( SingleLockState state){ | |
| 246 | return (strongUnlocking(state) || weakUnlocking(state)); | 246 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 247 | } | 247 | } | |
| 248 | private boolean strongUnlocking( SingleLockState state){ | 248 | private boolean strongUnlocking( SingleLockState state){ | |
| 249 | if (state != null) { | 249 | if (state != null) { | |
| 250 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 250 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 251 | } | 251 | } | |
| 252 | return false; | 252 | return false; | |
| 253 | } | 253 | } | |
| 254 | private boolean weakUnlocking( SingleLockState state){ | 254 | private boolean weakUnlocking( SingleLockState state){ | |
| 255 | if (state != null) { | 255 | if (state != null) { | |
| 256 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 256 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 257 | } | 257 | } | |
| 258 | return false; | 258 | return false; | |
| 259 | } | 259 | } | |
| 260 | private boolean locking( SingleLockState onCreateState){ | 260 | private boolean locking( SingleLockState onCreateState){ | |
| 261 | if (onCreateState != null) { | 261 | if (onCreateState != null) { | |
| 262 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 262 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 263 | } | 263 | } | |
| 264 | return false; | 264 | return false; | |
| 265 | } | 265 | } | |
| 266 | private Logger logger; | 266 | private Logger logger; | |
| 267 | private void logNote( String s){ | 267 | private void logNote( String s){ | |
| 268 | logger.add(s); | 268 | logger.add(s); | |
| 269 | } | 269 | } | |
| 270 | public Logger getLogger(){ | 270 | public Logger getLogger(){ | |
| 271 | return logger; | 271 | return logger; | |
| 272 | } | 272 | } | |
| 273 | private SingleLockState getServiceOnStart(){ | 273 | private SingleLockState getServiceOnStart(){ | |
| 274 | SingleLockState onStart=map.get("onStart"); | 274 | SingleLockState onStart=map.get("onStart"); | |
| 275 | SingleLockState onStartCommand=map.get("onStartCommand"); | 275 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 276 | if (onStartCommand == null) { | 276 | if (onStartCommand == null) { | |
| 277 | return onStart; | 277 | return onStart; | |
| 278 | } | 278 | } | |
| 279 | else { | 279 | else { | |
| 280 | return onStartCommand; | 280 | return onStartCommand; | |
| 281 | } | 281 | } | |
| 282 | } | 282 | } | |
| 283 | /** | 283 | /** | |
| 284 | * TODO: make sure the same lock is locked and unlocked... | 284 | * TODO: make sure the same lock is locked and unlocked... | |
| 285 | */ | 285 | */ | |
| 286 | public void solveFacts(){ | 286 | public void solveFacts(){ | |
| 287 | E.log(1,"Looking for: " + component.getComponentType()); | 287 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 288 | if (component.getComponentType().equals("Activity")) { | 288 | if (component.getComponentType().equals("Activity")) { | |
| 289 | SingleLockState onCreateState=map.get("onCreate"); | 289 | SingleLockState onCreateState=map.get("onCreate"); | |
| 290 | if (locking(onCreateState)) { | 290 | if (locking(onCreateState)) { | |
| 291 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 291 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 292 | } | 292 | } | |
| 293 | SingleLockState onStartState=map.get("onStart"); | 293 | SingleLockState onStartState=map.get("onStart"); | |
| 294 | if (locking(onStartState)) { | 294 | if (locking(onStartState)) { | |
| 295 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 295 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 296 | } | 296 | } | |
| 297 | SingleLockState onRestartState=map.get("onRestart"); | 297 | SingleLockState onRestartState=map.get("onRestart"); | |
| 298 | if (locking(onRestartState)) { | 298 | if (locking(onRestartState)) { | |
| 299 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 299 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 300 | } | 300 | } | |
| 301 | SingleLockState onPauseState=map.get("onPause"); | 301 | SingleLockState onPauseState=map.get("onPause"); | |
| 302 | SingleLockState onResumeState=map.get("onResume"); | 302 | SingleLockState onResumeState=map.get("onResume"); | |
| 303 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 303 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 304 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 304 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 305 | } | 305 | } | |
| 306 | } | 306 | } | |
| 307 | if (component.getComponentType().equals("Service")) { | 307 | if (component.getComponentType().equals("Service")) { | |
| 308 | SingleLockState onStartState=getServiceOnStart(); | 308 | SingleLockState onStartState=getServiceOnStart(); | |
| 309 | SingleLockState onDestroyState=map.get("onDestroy"); | 309 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 310 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 310 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 311 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 311 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 312 | } | 312 | } | |
| 313 | if (weakUnlocking(onDestroyState)) { | 313 | if (weakUnlocking(onDestroyState)) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 314 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | if (component.getComponentType().equals("RunnableThread")) { | 317 | if (component.getComponentType().equals("RunnableThread")) { | |
| 318 | SingleLockState runState=map.get("run"); | 318 | SingleLockState runState=map.get("run"); | |
| 319 | if (locking(runState)) { | 319 | if (locking(runState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | if (component.getComponentType().equals("Handler")) { | 323 | if (component.getComponentType().equals("Handler")) { | |
| 324 | SingleLockState runState=map.get("handleMessage"); | 324 | SingleLockState runState=map.get("handleMessage"); | |
| 325 | if (unlocking(runState) && (void)!strongUnlocking(runState)) { | 325 | if (unlocking(runState) && (!strongUnlocking(runState))) { | |
| 326 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 326 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 327 | } | 327 | } | |
| 328 | } | 328 | } | |
| 329 | if (component.getComponentType().equals("BroadcastReceiver")) { | 329 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 330 | SingleLockState onReceiveState=map.get("onReceive"); | 330 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 331 | if (locking(onReceiveState)) { | 331 | if (locking(onReceiveState)) { | |
| 332 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 332 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 333 | } | 333 | } | |
| 334 | } | 334 | } | |
| 335 | } | 335 | } | |
| 336 | } | 336 | } | |
| 337 | } | 337 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_039 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_040 | |||
|---|---|---|---|---|
|
337 lines 13098 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12890 bytes Last modified : Mon May 14 23:48:03 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:43.406 | 1 | //Time : 2012-04-24 19:02:47.732 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | ERROR: Encountered " "void" "void "" at line 325, column 37. | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | Was expecting one of: | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | "false" ... | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | "new" ... | 7 | changes = 4 | |
| 8 | "null" ... | 8 | changes to method solveFacts = 1 | |
| 9 | "super" ... | 9 | private/protected method declarations = 1 | |
| 10 | "this" ... | |||
| 11 | "true" ... | |||
| 12 | <LONG_LITERAL> ... | |||
| 13 | <INTEGER_LITERAL> ... | |||
| 14 | <FLOATING_POINT_LITERAL> ... | |||
| 15 | <CHARACTER_LITERAL> ... | |||
| 16 | <STRING_LITERAL> ... | |||
| 17 | <IDENTIFIER> ... | |||
| 18 | "(" ... | |||
| 19 | "!" ... | |||
| 20 | "~" ... | |||
| 21 | <IDENTIFIER> ... | |||
| 22 | "(" ... | |||
| 23 | ||||
| 24 | [Ljava.lang.StackTraceElement;@ba3bc8c = 1 | |||
| 25 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 26 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 27 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 28 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 29 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 30 | import java.util.Map; | 15 | import java.util.Map; | |
| 31 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 32 | import java.util.Set; | 17 | import java.util.Set; | |
| 33 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 34 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 36 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 37 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 38 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 39 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 40 | import energy.util.E; | 25 | import energy.util.E; | |
| 41 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 42 | /** | 27 | /** | |
| 43 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 44 | */ | 29 | */ | |
| 45 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 46 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 47 | private Component component; | 32 | private Component component; | |
| 48 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 49 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 50 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 51 | this.component=c; | 36 | this.component=c; | |
| 52 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 53 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 54 | } | 39 | } | |
| 55 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 56 | return allExitStates; | 41 | return allExitStates; | |
| 57 | } | 42 | } | |
| 58 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 59 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 60 | } | 45 | } | |
| 61 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 62 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 63 | } | 48 | } | |
| 64 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 65 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 66 | } | 51 | } | |
| 67 | public String toString(){ | 52 | public String toString(){ | |
| 68 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 69 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 70 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 71 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 72 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 73 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 74 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 75 | } | 60 | } | |
| 76 | } | 61 | } | |
| 77 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 78 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 79 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 80 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 81 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 82 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 83 | ; | 68 | ; | |
| 84 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 85 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 86 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 87 | } | 72 | } | |
| 88 | } | 73 | } | |
| 89 | } | 74 | } | |
| 90 | } | 75 | } | |
| 91 | return null; | 76 | return null; | |
| 92 | } | 77 | } | |
| 93 | } | 78 | } | |
| 94 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 95 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 96 | } | 81 | } | |
| 97 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 98 | /** | 83 | /** | |
| 99 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 100 | * @param component | 85 | * @param component | |
| 101 | */ | 86 | */ | |
| 102 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 103 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 104 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 105 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 106 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 107 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 108 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 109 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 110 | } | 95 | } | |
| 111 | } | 96 | } | |
| 112 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 113 | } | 98 | } | |
| 114 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 115 | if (runState != null) { | 100 | if (runState != null) { | |
| 116 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 117 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 118 | } | 103 | } | |
| 119 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 120 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 121 | } | 106 | } | |
| 122 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 123 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 124 | } | 109 | } | |
| 125 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 126 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 127 | } | 112 | } | |
| 128 | else { | 113 | else { | |
| 129 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 130 | } | 115 | } | |
| 131 | } | 116 | } | |
| 132 | else { | 117 | else { | |
| 133 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 134 | } | 119 | } | |
| 135 | } | 120 | } | |
| 136 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 137 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 138 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 139 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 140 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 141 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 142 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 143 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 144 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 145 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 146 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 147 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 148 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 149 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 150 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 151 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 152 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 153 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 155 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 156 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 157 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 158 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 159 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 160 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 161 | printMethod=true; | 146 | printMethod=true; | |
| 162 | } | 147 | } | |
| 163 | } | 148 | } | |
| 164 | if (printMethod) { | 149 | if (printMethod) { | |
| 165 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 166 | printComponent=true; | 151 | printComponent=true; | |
| 167 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 168 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 169 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 170 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 171 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 172 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 173 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 174 | } | 159 | } | |
| 175 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 176 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 177 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 178 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 179 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 180 | } | 165 | } | |
| 181 | else { | 166 | else { | |
| 182 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 183 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 184 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 185 | } | 170 | } | |
| 186 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 187 | } | 172 | } | |
| 188 | } | 173 | } | |
| 189 | } | 174 | } | |
| 190 | } | 175 | } | |
| 191 | if (printComponent) { | 176 | if (printComponent) { | |
| 192 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 193 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 194 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 195 | } | 180 | } | |
| 196 | } | 181 | } | |
| 197 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 198 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 199 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 200 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 201 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 202 | } | 187 | } | |
| 203 | } | 188 | } | |
| 204 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 205 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 206 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 207 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 208 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 209 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 210 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 211 | } | 196 | } | |
| 212 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 213 | } | 198 | } | |
| 214 | return result; | 199 | return result; | |
| 215 | } | 200 | } | |
| 216 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 217 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 218 | public void output(){ | 203 | public void output(){ | |
| 219 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 220 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 221 | } | 206 | } | |
| 222 | } | 207 | } | |
| 223 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 224 | return this; | 209 | return this; | |
| 225 | } | 210 | } | |
| 226 | public String toString(){ | 211 | public String toString(){ | |
| 227 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 228 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 229 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 230 | } | 215 | } | |
| 231 | return result.toString(); | 216 | return result.toString(); | |
| 232 | } | 217 | } | |
| 233 | } | 218 | } | |
| 234 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 235 | private Component component; | 220 | private Component component; | |
| 236 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 237 | this.component=component; | 222 | this.component=component; | |
| 238 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 239 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 240 | } | 225 | } | |
| 241 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 242 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 243 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 244 | } | 229 | } | |
| 245 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 246 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 247 | } | 232 | } | |
| 248 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 249 | if (state != null) { | 234 | if (state != null) { | |
| 250 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 251 | } | 236 | } | |
| 252 | return false; | 237 | return false; | |
| 253 | } | 238 | } | |
| 254 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 255 | if (state != null) { | 240 | if (state != null) { | |
| 256 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 257 | } | 242 | } | |
| 258 | return false; | 243 | return false; | |
| 259 | } | 244 | } | |
| 260 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 261 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 262 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 263 | } | 248 | } | |
| 264 | return false; | 249 | return false; | |
| 265 | } | 250 | } | |
| 266 | private Logger logger; | 251 | private Logger logger; | |
| 267 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 268 | logger.add(s); | 253 | logger.add(s); | |
| 269 | } | 254 | } | |
| 270 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 271 | return logger; | 256 | return logger; | |
| 272 | } | 257 | } | |
| 273 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 274 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 275 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 276 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 277 | return onStart; | 262 | return onStart; | |
| 278 | } | 263 | } | |
| 279 | else { | 264 | else { | |
| 280 | return onStartCommand; | 265 | return onStartCommand; | |
| 281 | } | 266 | } | |
| 282 | } | 267 | } | |
| 283 | /** | 268 | /** | |
| 284 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 285 | */ | 270 | */ | |
| 286 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 287 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 288 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 289 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 290 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 291 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 292 | } | 277 | } | |
| 293 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 294 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 295 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 296 | } | 281 | } | |
| 297 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 298 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 299 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 300 | } | 285 | } | |
| 301 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 302 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 303 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 304 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 305 | } | 290 | } | |
| 306 | } | 291 | } | |
| 307 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 308 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 309 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 310 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 311 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 312 | } | 297 | } | |
| 313 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 315 | } | 300 | } | |
| 316 | } | 301 | } | |
| 317 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 318 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 319 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 321 | } | 306 | } | |
| 322 | } | 307 | } | |
| 323 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 324 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 325 | if (unlocking(runState) && (!strongUnlocking(runState))) { | 310 | if (unlocking(runState) && !strongUnlocking(runState)) { | |
| 326 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 327 | } | 312 | } | |
| 328 | } | 313 | } | |
| 329 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 330 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 331 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 332 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 333 | } | 318 | } | |
| 334 | } | 319 | } | |
| 335 | } | 320 | } | |
| 336 | } | 321 | } | |
| 337 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_040 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_041 | |||
|---|---|---|---|---|
|
322 lines 12890 bytes Last modified : Mon May 14 23:48:03 2012 |
322 lines 12892 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:47.732 | 1 | //Time : 2012-04-24 19:02:49.537 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 309 | SingleLockState runState=map.get("handleMessage"); | |
| 310 | if (unlocking(runState) && !strongUnlocking(runState)) { | 310 | if (unlocking(runState) && (!strongUnlocking(runState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_041 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_045 | |||
|---|---|---|---|---|
|
322 lines 12892 bytes Last modified : Mon May 14 23:48:04 2012 |
316 lines 12660 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:49.537 | 1 | //Time : 2012-04-24 19:02:58.676 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE IfStmt to IfStmt = 2 | |||
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 7 | changes = 4 | |||
| 8 | changes to method solveFacts = 1 | |||
| 9 | private/protected method declarations = 1 | |||
| 10 | */package energy.analysis; | 4 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 5 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 6 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 7 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 8 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 9 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 10 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 11 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 12 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 13 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 14 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 15 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 16 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 17 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 18 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 19 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 20 | public class AnalysisResults { | |
| 27 | /** | 21 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 22 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 23 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 24 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 25 | public class ComponentSummary { | |
| 32 | private Component component; | 26 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 27 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 28 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 29 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 30 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 31 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 32 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 33 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 34 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 35 | return allExitStates; | |
| 42 | } | 36 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 37 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 38 | allExitStates.put(n,st); | |
| 45 | } | 39 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 40 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 41 | callBackExitStates.put(cb,st); | |
| 48 | } | 42 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 43 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 44 | return allExitStates.get(method); | |
| 51 | } | 45 | } | |
| 52 | public String toString(){ | 46 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 47 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 48 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 49 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 50 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 51 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 52 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 53 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 54 | } | |
| 61 | } | 55 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 56 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 57 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 58 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 59 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 60 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 61 | String name=cb.getName(); | |
| 68 | ; | 62 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 63 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 64 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 65 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 66 | } | |
| 73 | } | 67 | } | |
| 74 | } | 68 | } | |
| 75 | } | 69 | } | |
| 76 | return null; | 70 | return null; | |
| 77 | } | 71 | } | |
| 78 | } | 72 | } | |
| 79 | public AnalysisResults(){ | 73 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 74 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 75 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 76 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 77 | /** | |
| 84 | * Invoke this after the component has been analyzed | 78 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 79 | * @param component | |
| 86 | */ | 80 | */ | |
| 87 | public void createComponentSummary( Component component){ | 81 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 82 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 83 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 84 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 85 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 86 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 87 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 88 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 89 | } | |
| 96 | } | 90 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 91 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 92 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 93 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 94 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 95 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 96 | return LockUsage.LOCKING; | |
| 103 | } | 97 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 98 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 99 | return LockUsage.EMPTY; | |
| 106 | } | 100 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 101 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 102 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 103 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 104 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 105 | return LockUsage.UNLOCKING; | |
| 112 | } | 106 | } | |
| 113 | else { | 107 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 108 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 109 | } | |
| 116 | } | 110 | } | |
| 117 | else { | 111 | else { | |
| 118 | return LockUsage.EMPTY; | 112 | return LockUsage.EMPTY; | |
| 119 | } | 113 | } | |
| 120 | } | 114 | } | |
| 121 | public ArrayList<String> processResults(){ | 115 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 116 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 117 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 118 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 119 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 120 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 121 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 122 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 123 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 124 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 125 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 126 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 127 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 128 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 129 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 130 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 131 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 132 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 133 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 134 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 135 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 136 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 137 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 138 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 139 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 140 | printMethod=true; | |
| 147 | } | 141 | } | |
| 148 | } | 142 | } | |
| 149 | if (printMethod) { | 143 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 144 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 145 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 146 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 147 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 148 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 149 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 150 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 151 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 152 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 153 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 154 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 155 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 156 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 157 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 158 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 159 | } | |
| 166 | else { | 160 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 161 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 162 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 163 | usageMap.put(lu,set); | |
| 170 | } | 164 | } | |
| 171 | policy.addFact(node,mergedLS); | 165 | policy.addFact(node,mergedLS); | |
| 172 | } | 166 | } | |
| 173 | } | 167 | } | |
| 174 | } | 168 | } | |
| 175 | } | 169 | } | |
| 176 | if (printComponent) { | 170 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 171 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 172 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 173 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 174 | } | |
| 181 | } | 175 | } | |
| 182 | System.out.println("==========================================\n"); | 176 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 177 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 178 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 179 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 180 | System.out.println(" " + s.toString()); | |
| 187 | } | 181 | } | |
| 188 | } | 182 | } | |
| 189 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 184 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 185 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 186 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 187 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 188 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 189 | System.out.println("\n"); | |
| 196 | } | 190 | } | |
| 197 | result=logger.getStringList(); | 191 | result=logger.getStringList(); | |
| 198 | } | 192 | } | |
| 199 | return result; | 193 | return result; | |
| 200 | } | 194 | } | |
| 201 | public class Logger extends ArrayList<String> { | 195 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 196 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 197 | public void output(){ | |
| 204 | for ( String s : this) { | 198 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 199 | System.out.println(" " + s); | |
| 206 | } | 200 | } | |
| 207 | } | 201 | } | |
| 208 | public ArrayList<String> getStringList(){ | 202 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 203 | return this; | |
| 210 | } | 204 | } | |
| 211 | public String toString(){ | 205 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 206 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 207 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 208 | result.append(s + "\n"); | |
| 215 | } | 209 | } | |
| 216 | return result.toString(); | 210 | return result.toString(); | |
| 217 | } | 211 | } | |
| 218 | } | 212 | } | |
| 219 | public class ComponentPolicy { | 213 | public class ComponentPolicy { | |
| 220 | private Component component; | 214 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 215 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 216 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 217 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 218 | logger=new Logger(); | |
| 225 | } | 219 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 220 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 221 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 222 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 223 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 224 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 225 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 226 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 227 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 228 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 229 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 230 | } | |
| 237 | return false; | 231 | return false; | |
| 238 | } | 232 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 233 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 234 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 236 | } | |
| 243 | return false; | 237 | return false; | |
| 244 | } | 238 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 239 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 240 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 241 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 242 | } | |
| 249 | return false; | 243 | return false; | |
| 250 | } | 244 | } | |
| 251 | private Logger logger; | 245 | private Logger logger; | |
| 252 | private void logNote( String s){ | 246 | private void logNote( String s){ | |
| 253 | logger.add(s); | 247 | logger.add(s); | |
| 254 | } | 248 | } | |
| 255 | public Logger getLogger(){ | 249 | public Logger getLogger(){ | |
| 256 | return logger; | 250 | return logger; | |
| 257 | } | 251 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 252 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 253 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 254 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 255 | if (onStartCommand == null) { | |
| 262 | return onStart; | 256 | return onStart; | |
| 263 | } | 257 | } | |
| 264 | else { | 258 | else { | |
| 265 | return onStartCommand; | 259 | return onStartCommand; | |
| 266 | } | 260 | } | |
| 267 | } | 261 | } | |
| 268 | /** | 262 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 263 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 264 | */ | |
| 271 | public void solveFacts(){ | 265 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 266 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 267 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 268 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 269 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 270 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 271 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 272 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 273 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 274 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 275 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 276 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 277 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 278 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 279 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 280 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 281 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 282 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 283 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 284 | } | |
| 291 | } | 285 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 286 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 287 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 288 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 289 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 290 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 291 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 292 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 293 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 294 | } | |
| 301 | } | 295 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 296 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 297 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 298 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 299 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 300 | } | |
| 307 | } | 301 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 302 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState runState=map.get("handleMessage"); | 303 | SingleLockState handleState=map.get("handleMessage"); | |
| 310 | if (unlocking(runState) && (!strongUnlocking(runState))) { | 304 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 312 | } | 306 | } | |
| 313 | } | 307 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 308 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 309 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 310 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 312 | } | |
| 319 | } | 313 | } | |
| 320 | } | 314 | } | |
| 321 | } | 315 | } | |
| 322 | } | 316 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_045 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_046 | |||
|---|---|---|---|---|
|
316 lines 12660 bytes Last modified : Mon May 14 23:48:04 2012 |
323 lines 12957 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:02:58.676 | 1 | //Time : 2012-04-24 19:03:04.851 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 8 | changes = 5 | |||
| 9 | changes to method solveFacts = 1 | |||
| 10 | private/protected method declarations = 1 | |||
| 4 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 5 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 6 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 7 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 8 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 9 | import java.util.Map; | 16 | import java.util.Map; | |
| 10 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 11 | import java.util.Set; | 18 | import java.util.Set; | |
| 12 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 13 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 14 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 15 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 16 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 17 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 18 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 19 | import energy.util.E; | 26 | import energy.util.E; | |
| 20 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 21 | /** | 28 | /** | |
| 22 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 23 | */ | 30 | */ | |
| 24 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 25 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 26 | private Component component; | 33 | private Component component; | |
| 27 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 28 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 29 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 30 | this.component=c; | 37 | this.component=c; | |
| 31 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 32 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 33 | } | 40 | } | |
| 34 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 35 | return allExitStates; | 42 | return allExitStates; | |
| 36 | } | 43 | } | |
| 37 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 38 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 39 | } | 46 | } | |
| 40 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 41 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 42 | } | 49 | } | |
| 43 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 44 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 45 | } | 52 | } | |
| 46 | public String toString(){ | 53 | public String toString(){ | |
| 47 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 48 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 49 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 50 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 51 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 52 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 53 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 54 | } | 61 | } | |
| 55 | } | 62 | } | |
| 56 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 57 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 58 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 59 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 60 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 61 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 62 | ; | 69 | ; | |
| 63 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 64 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 65 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 66 | } | 73 | } | |
| 67 | } | 74 | } | |
| 68 | } | 75 | } | |
| 69 | } | 76 | } | |
| 70 | return null; | 77 | return null; | |
| 71 | } | 78 | } | |
| 72 | } | 79 | } | |
| 73 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 74 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 75 | } | 82 | } | |
| 76 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 77 | /** | 84 | /** | |
| 78 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 79 | * @param component | 86 | * @param component | |
| 80 | */ | 87 | */ | |
| 81 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 82 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 83 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 84 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 85 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 86 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 87 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 88 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 89 | } | 96 | } | |
| 90 | } | 97 | } | |
| 91 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 92 | } | 99 | } | |
| 93 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 94 | if (runState != null) { | 101 | if (runState != null) { | |
| 95 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 96 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 97 | } | 104 | } | |
| 98 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 99 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 100 | } | 107 | } | |
| 101 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 102 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 103 | } | 110 | } | |
| 104 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 105 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 106 | } | 113 | } | |
| 107 | else { | 114 | else { | |
| 108 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 109 | } | 116 | } | |
| 110 | } | 117 | } | |
| 111 | else { | 118 | else { | |
| 112 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 113 | } | 120 | } | |
| 114 | } | 121 | } | |
| 115 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 116 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 117 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 118 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 119 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 120 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 121 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 122 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 123 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 124 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 125 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 126 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 127 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 128 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 129 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 130 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 131 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 132 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 133 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 134 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 135 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 136 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 137 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 138 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 139 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 140 | printMethod=true; | 147 | printMethod=true; | |
| 141 | } | 148 | } | |
| 142 | } | 149 | } | |
| 143 | if (printMethod) { | 150 | if (printMethod) { | |
| 144 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 145 | printComponent=true; | 152 | printComponent=true; | |
| 146 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 147 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 148 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 149 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 150 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 151 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 152 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 153 | } | 160 | } | |
| 154 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 155 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 156 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 157 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 158 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 159 | } | 166 | } | |
| 160 | else { | 167 | else { | |
| 161 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 162 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 163 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 164 | } | 171 | } | |
| 165 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 166 | } | 173 | } | |
| 167 | } | 174 | } | |
| 168 | } | 175 | } | |
| 169 | } | 176 | } | |
| 170 | if (printComponent) { | 177 | if (printComponent) { | |
| 171 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 172 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 173 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 174 | } | 181 | } | |
| 175 | } | 182 | } | |
| 176 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 177 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 178 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 179 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 180 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 181 | } | 188 | } | |
| 182 | } | 189 | } | |
| 183 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 184 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 185 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 186 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 187 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 188 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 189 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 190 | } | 197 | } | |
| 191 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 192 | } | 199 | } | |
| 193 | return result; | 200 | return result; | |
| 194 | } | 201 | } | |
| 195 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 196 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 197 | public void output(){ | 204 | public void output(){ | |
| 198 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 199 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 200 | } | 207 | } | |
| 201 | } | 208 | } | |
| 202 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 203 | return this; | 210 | return this; | |
| 204 | } | 211 | } | |
| 205 | public String toString(){ | 212 | public String toString(){ | |
| 206 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 207 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 208 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 209 | } | 216 | } | |
| 210 | return result.toString(); | 217 | return result.toString(); | |
| 211 | } | 218 | } | |
| 212 | } | 219 | } | |
| 213 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 214 | private Component component; | 221 | private Component component; | |
| 215 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 216 | this.component=component; | 223 | this.component=component; | |
| 217 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 218 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 219 | } | 226 | } | |
| 220 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 221 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 222 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 223 | } | 230 | } | |
| 224 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 225 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 226 | } | 233 | } | |
| 227 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 228 | if (state != null) { | 235 | if (state != null) { | |
| 229 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 230 | } | 237 | } | |
| 231 | return false; | 238 | return false; | |
| 232 | } | 239 | } | |
| 233 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 241 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 236 | } | 243 | } | |
| 237 | return false; | 244 | return false; | |
| 238 | } | 245 | } | |
| 239 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 240 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 241 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 242 | } | 249 | } | |
| 243 | return false; | 250 | return false; | |
| 244 | } | 251 | } | |
| 245 | private Logger logger; | 252 | private Logger logger; | |
| 246 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 247 | logger.add(s); | 254 | logger.add(s); | |
| 248 | } | 255 | } | |
| 249 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 250 | return logger; | 257 | return logger; | |
| 251 | } | 258 | } | |
| 252 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 253 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 254 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 255 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 256 | return onStart; | 263 | return onStart; | |
| 257 | } | 264 | } | |
| 258 | else { | 265 | else { | |
| 259 | return onStartCommand; | 266 | return onStartCommand; | |
| 260 | } | 267 | } | |
| 261 | } | 268 | } | |
| 262 | /** | 269 | /** | |
| 263 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 264 | */ | 271 | */ | |
| 265 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 266 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 267 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 268 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 269 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 270 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 271 | } | 278 | } | |
| 272 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 273 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 274 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 275 | } | 282 | } | |
| 276 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 277 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 278 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 279 | } | 286 | } | |
| 280 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 281 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 282 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 283 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 284 | } | 291 | } | |
| 285 | } | 292 | } | |
| 286 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 287 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 288 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 289 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 290 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 291 | } | 298 | } | |
| 292 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 293 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 294 | } | 301 | } | |
| 295 | } | 302 | } | |
| 296 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 297 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 298 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 300 | } | 307 | } | |
| 301 | } | 308 | } | |
| 302 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 303 | SingleLockState handleState=map.get("handleMessage"); | 310 | SingleLockState handleState=map.get("handleMessage"); | |
| 304 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ handleMessage"); | |
| 306 | } | 313 | } | |
| 307 | } | 314 | } | |
| 308 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 309 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 310 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 312 | } | 319 | } | |
| 313 | } | 320 | } | |
| 314 | } | 321 | } | |
| 315 | } | 322 | } | |
| 316 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_046 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_047 | |||
|---|---|---|---|---|
|
323 lines 12957 bytes Last modified : Mon May 14 23:48:04 2012 |
323 lines 12961 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:04.851 | 1 | //Time : 2012-04-24 19:03:06.680 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState handleState=map.get("handleMessage"); | 310 | SingleLockState handleState=map.get("handleMessage"); | |
| 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Locking @ handleMessage"); | 312 | logNote("WEAK BUG: " + component.toString() + "Not Locking @ handleMessage"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_047 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_048 | |||
|---|---|---|---|---|
|
323 lines 12961 bytes Last modified : Mon May 14 23:48:04 2012 |
323 lines 12965 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:06.680 | 1 | //Time : 2012-04-24 19:03:08.478 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState handleState=map.get("handleMessage"); | 310 | SingleLockState handleState=map.get("handleMessage"); | |
| 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Not Locking @ handleMessage"); | 312 | logNote("WEAK BUG: " + component.toString() + "Not fullLocking @ handleMessage"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_048 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_049 | |||
|---|---|---|---|---|
|
323 lines 12965 bytes Last modified : Mon May 14 23:48:04 2012 |
323 lines 12967 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:08.478 | 1 | //Time : 2012-04-24 19:03:10.259 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState handleState=map.get("handleMessage"); | 310 | SingleLockState handleState=map.get("handleMessage"); | |
| 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Not fullLocking @ handleMessage"); | 312 | logNote("WEAK BUG: " + component.toString() + "Not full unocking @ handleMessage"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_049 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_050 | |||
|---|---|---|---|---|
|
323 lines 12967 bytes Last modified : Mon May 14 23:48:04 2012 |
323 lines 12968 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:10.259 | 1 | //Time : 2012-04-24 19:03:11.564 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return false; | 238 | return false; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return false; | 244 | return false; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | } | 292 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 293 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 294 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 295 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 298 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 299 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | } | 302 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 303 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 304 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 305 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 307 | } | |
| 308 | } | 308 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 309 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState handleState=map.get("handleMessage"); | 310 | SingleLockState handleState=map.get("handleMessage"); | |
| 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Not full unocking @ handleMessage"); | 312 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 313 | } | 313 | } | |
| 314 | } | 314 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 316 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 317 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_050 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_051 | |||
|---|---|---|---|---|
|
323 lines 12968 bytes Last modified : Mon May 14 23:48:04 2012 |
322 lines 12926 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:03:11.564 | 1 | //Time : 2012-04-24 19:07:41.313 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 7 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 15 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 17 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 25 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 28 | /** | 27 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 29 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 33 | private Component component; | 32 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 36 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 39 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 41 | return allExitStates; | |
| 43 | } | 42 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 46 | } | 45 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 49 | } | 48 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 52 | } | 51 | } | |
| 53 | public String toString(){ | 52 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 60 | } | |
| 62 | } | 61 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 69 | ; | 68 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 72 | } | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | return null; | 76 | return null; | |
| 78 | } | 77 | } | |
| 79 | } | 78 | } | |
| 80 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 81 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 83 | /** | |
| 85 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 85 | * @param component | |
| 87 | */ | 86 | */ | |
| 88 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 95 | } | |
| 97 | } | 96 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 98 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 100 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 104 | } | 103 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 107 | } | 106 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 109 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 113 | } | 112 | } | |
| 114 | else { | 113 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 115 | } | |
| 117 | } | 116 | } | |
| 118 | else { | 117 | else { | |
| 119 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 120 | } | 119 | } | |
| 121 | } | 120 | } | |
| 122 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 146 | printMethod=true; | |
| 148 | } | 147 | } | |
| 149 | } | 148 | } | |
| 150 | if (printMethod) { | 149 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 151 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 159 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 165 | } | |
| 167 | else { | 166 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 171 | } | 170 | } | |
| 172 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 173 | } | 172 | } | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | if (printComponent) { | 176 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 180 | } | |
| 182 | } | 181 | } | |
| 183 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 188 | } | 187 | } | |
| 189 | } | 188 | } | |
| 190 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 197 | } | 196 | } | |
| 198 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 199 | } | 198 | } | |
| 200 | return result; | 199 | return result; | |
| 201 | } | 200 | } | |
| 202 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 203 | public void output(){ | |
| 205 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 207 | } | 206 | } | |
| 208 | } | 207 | } | |
| 209 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 209 | return this; | |
| 211 | } | 210 | } | |
| 212 | public String toString(){ | 211 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 216 | } | 215 | } | |
| 217 | return result.toString(); | 216 | return result.toString(); | |
| 218 | } | 217 | } | |
| 219 | } | 218 | } | |
| 220 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 221 | private Component component; | 220 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 222 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 226 | } | 225 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 229 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 232 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 234 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 236 | } | |
| 238 | return false; | 237 | return false; | |
| 239 | } | 238 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 240 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 242 | } | |
| 244 | return false; | 243 | return false; | |
| 245 | } | 244 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 248 | } | |
| 250 | return false; | 249 | return false; | |
| 251 | } | 250 | } | |
| 252 | private Logger logger; | 251 | private Logger logger; | |
| 253 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 254 | logger.add(s); | 253 | logger.add(s); | |
| 255 | } | 254 | } | |
| 256 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 257 | return logger; | 256 | return logger; | |
| 258 | } | 257 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 263 | return onStart; | 262 | return onStart; | |
| 264 | } | 263 | } | |
| 265 | else { | 264 | else { | |
| 266 | return onStartCommand; | 265 | return onStartCommand; | |
| 267 | } | 266 | } | |
| 268 | } | 267 | } | |
| 269 | /** | 268 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 270 | */ | |
| 272 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 281 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (locking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (weaklocking(onResumeState) && (!unlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 290 | } | |
| 292 | } | 291 | } | |
| 293 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 294 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 295 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 296 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 297 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 298 | } | 297 | } | |
| 299 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 300 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 301 | } | 300 | } | |
| 302 | } | 301 | } | |
| 303 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 304 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 305 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 306 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 307 | } | 306 | } | |
| 308 | } | 307 | } | |
| 309 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 310 | SingleLockState handleState=map.get("handleMessage"); | 309 | SingleLockState handleState=map.get("handleMessage"); | |
| 311 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 312 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 313 | } | 312 | } | |
| 314 | } | 313 | } | |
| 315 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 316 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 317 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 318 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 319 | } | 318 | } | |
| 320 | } | 319 | } | |
| 321 | } | 320 | } | |
| 322 | } | 321 | } | |
| 323 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_051 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_052 | |||
|---|---|---|---|---|
|
322 lines 12926 bytes Last modified : Mon May 14 23:48:04 2012 |
322 lines 12925 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:41.313 | 1 | //Time : 2012-04-24 19:07:44.650 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (weaklocking(onResumeState) && (!unlocking(onPauseState))) { | 288 | if (weaklocking(onPasueState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState handleState=map.get("handleMessage"); | 309 | SingleLockState handleState=map.get("handleMessage"); | |
| 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_052 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_053 | |||
|---|---|---|---|---|
|
322 lines 12925 bytes Last modified : Mon May 14 23:48:04 2012 |
322 lines 12925 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:44.650 | 1 | //Time : 2012-04-24 19:07:46.935 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (weaklocking(onPasueState) && (!unlocking(onPauseState))) { | 288 | if (weaklocking(onPauseState) && (!unlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState handleState=map.get("handleMessage"); | 309 | SingleLockState handleState=map.get("handleMessage"); | |
| 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_053 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_054 | |||
|---|---|---|---|---|
|
322 lines 12925 bytes Last modified : Mon May 14 23:48:04 2012 |
322 lines 12931 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:46.935 | 1 | //Time : 2012-04-24 19:07:52.334 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (weaklocking(onPauseState) && (!unlocking(onPauseState))) { | 288 | if (weaklocking(onPauseState) && (!strongunlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | } | 291 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 297 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | } | 301 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 306 | } | |
| 307 | } | 307 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState handleState=map.get("handleMessage"); | 309 | SingleLockState handleState=map.get("handleMessage"); | |
| 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 312 | } | 312 | } | |
| 313 | } | 313 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | } | 320 | } | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_054 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_056 | |||
|---|---|---|---|---|
|
322 lines 12931 bytes Last modified : Mon May 14 23:48:04 2012 |
316 lines 12690 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:52.334 | 1 | //Time : 2012-04-24 19:07:57.191 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE IfStmt to IfStmt = 2 | |||
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 7 | changes = 4 | |||
| 8 | changes to method solveFacts = 1 | |||
| 9 | private/protected method declarations = 1 | |||
| 10 | */package energy.analysis; | 4 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 5 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 6 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 7 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 8 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 9 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 10 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 11 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 12 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 13 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 14 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 15 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 16 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 17 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 18 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 19 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 20 | public class AnalysisResults { | |
| 27 | /** | 21 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 22 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 23 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 24 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 25 | public class ComponentSummary { | |
| 32 | private Component component; | 26 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 27 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 28 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 29 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 30 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 31 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 32 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 33 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 34 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 35 | return allExitStates; | |
| 42 | } | 36 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 37 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 38 | allExitStates.put(n,st); | |
| 45 | } | 39 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 40 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 41 | callBackExitStates.put(cb,st); | |
| 48 | } | 42 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 43 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 44 | return allExitStates.get(method); | |
| 51 | } | 45 | } | |
| 52 | public String toString(){ | 46 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 47 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 48 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 49 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 50 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 51 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 52 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 53 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 54 | } | |
| 61 | } | 55 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 56 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 57 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 58 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 59 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 60 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 61 | String name=cb.getName(); | |
| 68 | ; | 62 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 63 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 64 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 65 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 66 | } | |
| 73 | } | 67 | } | |
| 74 | } | 68 | } | |
| 75 | } | 69 | } | |
| 76 | return null; | 70 | return null; | |
| 77 | } | 71 | } | |
| 78 | } | 72 | } | |
| 79 | public AnalysisResults(){ | 73 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 74 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 75 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 76 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 77 | /** | |
| 84 | * Invoke this after the component has been analyzed | 78 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 79 | * @param component | |
| 86 | */ | 80 | */ | |
| 87 | public void createComponentSummary( Component component){ | 81 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 82 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 83 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 84 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 85 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 86 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 87 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 88 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 89 | } | |
| 96 | } | 90 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 91 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 92 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 93 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 94 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 95 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 96 | return LockUsage.LOCKING; | |
| 103 | } | 97 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 98 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 99 | return LockUsage.EMPTY; | |
| 106 | } | 100 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 101 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 102 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 103 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 104 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 105 | return LockUsage.UNLOCKING; | |
| 112 | } | 106 | } | |
| 113 | else { | 107 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 108 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 109 | } | |
| 116 | } | 110 | } | |
| 117 | else { | 111 | else { | |
| 118 | return LockUsage.EMPTY; | 112 | return LockUsage.EMPTY; | |
| 119 | } | 113 | } | |
| 120 | } | 114 | } | |
| 121 | public ArrayList<String> processResults(){ | 115 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 116 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 117 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 118 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 119 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 120 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 121 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 122 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 123 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 124 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 125 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 126 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 127 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 128 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 129 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 130 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 131 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 132 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 133 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 134 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 135 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 136 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 137 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 138 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 139 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 140 | printMethod=true; | |
| 147 | } | 141 | } | |
| 148 | } | 142 | } | |
| 149 | if (printMethod) { | 143 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 144 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 145 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 146 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 147 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 148 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 149 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 150 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 151 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 152 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 153 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 154 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 155 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 156 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 157 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 158 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 159 | } | |
| 166 | else { | 160 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 161 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 162 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 163 | usageMap.put(lu,set); | |
| 170 | } | 164 | } | |
| 171 | policy.addFact(node,mergedLS); | 165 | policy.addFact(node,mergedLS); | |
| 172 | } | 166 | } | |
| 173 | } | 167 | } | |
| 174 | } | 168 | } | |
| 175 | } | 169 | } | |
| 176 | if (printComponent) { | 170 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 171 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 172 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 173 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 174 | } | |
| 181 | } | 175 | } | |
| 182 | System.out.println("==========================================\n"); | 176 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 177 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 178 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 179 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 180 | System.out.println(" " + s.toString()); | |
| 187 | } | 181 | } | |
| 188 | } | 182 | } | |
| 189 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 184 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 185 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 186 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 187 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 188 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 189 | System.out.println("\n"); | |
| 196 | } | 190 | } | |
| 197 | result=logger.getStringList(); | 191 | result=logger.getStringList(); | |
| 198 | } | 192 | } | |
| 199 | return result; | 193 | return result; | |
| 200 | } | 194 | } | |
| 201 | public class Logger extends ArrayList<String> { | 195 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 196 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 197 | public void output(){ | |
| 204 | for ( String s : this) { | 198 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 199 | System.out.println(" " + s); | |
| 206 | } | 200 | } | |
| 207 | } | 201 | } | |
| 208 | public ArrayList<String> getStringList(){ | 202 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 203 | return this; | |
| 210 | } | 204 | } | |
| 211 | public String toString(){ | 205 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 206 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 207 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 208 | result.append(s + "\n"); | |
| 215 | } | 209 | } | |
| 216 | return result.toString(); | 210 | return result.toString(); | |
| 217 | } | 211 | } | |
| 218 | } | 212 | } | |
| 219 | public class ComponentPolicy { | 213 | public class ComponentPolicy { | |
| 220 | private Component component; | 214 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 215 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 216 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 217 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 218 | logger=new Logger(); | |
| 225 | } | 219 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 220 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 221 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 222 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 223 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 224 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 225 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 226 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 227 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 228 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 229 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 230 | } | |
| 237 | return false; | 231 | return false; | |
| 238 | } | 232 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 233 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 234 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 236 | } | |
| 243 | return false; | 237 | return false; | |
| 244 | } | 238 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 239 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 240 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 241 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 242 | } | |
| 249 | return false; | 243 | return false; | |
| 250 | } | 244 | } | |
| 251 | private Logger logger; | 245 | private Logger logger; | |
| 252 | private void logNote( String s){ | 246 | private void logNote( String s){ | |
| 253 | logger.add(s); | 247 | logger.add(s); | |
| 254 | } | 248 | } | |
| 255 | public Logger getLogger(){ | 249 | public Logger getLogger(){ | |
| 256 | return logger; | 250 | return logger; | |
| 257 | } | 251 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 252 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 253 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 254 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 255 | if (onStartCommand == null) { | |
| 262 | return onStart; | 256 | return onStart; | |
| 263 | } | 257 | } | |
| 264 | else { | 258 | else { | |
| 265 | return onStartCommand; | 259 | return onStartCommand; | |
| 266 | } | 260 | } | |
| 267 | } | 261 | } | |
| 268 | /** | 262 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 263 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 264 | */ | |
| 271 | public void solveFacts(){ | 265 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 266 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 267 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 268 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 269 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 270 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 271 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 272 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 273 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 274 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 275 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 276 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 277 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 278 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 279 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 280 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 281 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (weaklocking(onPauseState) && (!strongunlocking(onPauseState))) { | 282 | if (weaklocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 283 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 284 | } | |
| 291 | } | 285 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 286 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 287 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 288 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 289 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 290 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 291 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 292 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 293 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 294 | } | |
| 301 | } | 295 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 296 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 297 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 298 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 299 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 300 | } | |
| 307 | } | 301 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 302 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState handleState=map.get("handleMessage"); | 303 | SingleLockState handleState=map.get("handleMessage"); | |
| 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 304 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 305 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 312 | } | 306 | } | |
| 313 | } | 307 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 308 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 309 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 310 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 312 | } | |
| 319 | } | 313 | } | |
| 320 | } | 314 | } | |
| 321 | } | 315 | } | |
| 322 | } | 316 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_056 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_057 | |||
|---|---|---|---|---|
|
316 lines 12690 bytes Last modified : Mon May 14 23:48:04 2012 |
322 lines 12933 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:07:57.191 | 1 | //Time : 2012-04-24 19:08:01.483 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE IfStmt to IfStmt = 2 | |||
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 7 | changes = 4 | |||
| 8 | changes to method solveFacts = 1 | |||
| 9 | private/protected method declarations = 1 | |||
| 4 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 5 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 6 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 7 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 8 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 9 | import java.util.Map; | 15 | import java.util.Map; | |
| 10 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 11 | import java.util.Set; | 17 | import java.util.Set; | |
| 12 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 13 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 14 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 15 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 16 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 17 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 18 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 19 | import energy.util.E; | 25 | import energy.util.E; | |
| 20 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 21 | /** | 27 | /** | |
| 22 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 23 | */ | 29 | */ | |
| 24 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 25 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 26 | private Component component; | 32 | private Component component; | |
| 27 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 28 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 29 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 30 | this.component=c; | 36 | this.component=c; | |
| 31 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 32 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 33 | } | 39 | } | |
| 34 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 35 | return allExitStates; | 41 | return allExitStates; | |
| 36 | } | 42 | } | |
| 37 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 38 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 39 | } | 45 | } | |
| 40 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 41 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 42 | } | 48 | } | |
| 43 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 44 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 45 | } | 51 | } | |
| 46 | public String toString(){ | 52 | public String toString(){ | |
| 47 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 48 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 49 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 50 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 51 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 52 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 53 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 54 | } | 60 | } | |
| 55 | } | 61 | } | |
| 56 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 57 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 58 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 59 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 60 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 61 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 62 | ; | 68 | ; | |
| 63 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 64 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 65 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 66 | } | 72 | } | |
| 67 | } | 73 | } | |
| 68 | } | 74 | } | |
| 69 | } | 75 | } | |
| 70 | return null; | 76 | return null; | |
| 71 | } | 77 | } | |
| 72 | } | 78 | } | |
| 73 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 74 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 75 | } | 81 | } | |
| 76 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 77 | /** | 83 | /** | |
| 78 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 79 | * @param component | 85 | * @param component | |
| 80 | */ | 86 | */ | |
| 81 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 82 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 83 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 84 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 85 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 86 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 87 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 88 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 89 | } | 95 | } | |
| 90 | } | 96 | } | |
| 91 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 92 | } | 98 | } | |
| 93 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 94 | if (runState != null) { | 100 | if (runState != null) { | |
| 95 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 96 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 97 | } | 103 | } | |
| 98 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 99 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 100 | } | 106 | } | |
| 101 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 102 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 103 | } | 109 | } | |
| 104 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 105 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 106 | } | 112 | } | |
| 107 | else { | 113 | else { | |
| 108 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 109 | } | 115 | } | |
| 110 | } | 116 | } | |
| 111 | else { | 117 | else { | |
| 112 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 113 | } | 119 | } | |
| 114 | } | 120 | } | |
| 115 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 116 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 117 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 118 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 119 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 120 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 121 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 122 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 123 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 124 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 125 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 126 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 127 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 128 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 129 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 130 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 131 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 132 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 133 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 134 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 135 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 136 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 137 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 138 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 139 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 140 | printMethod=true; | 146 | printMethod=true; | |
| 141 | } | 147 | } | |
| 142 | } | 148 | } | |
| 143 | if (printMethod) { | 149 | if (printMethod) { | |
| 144 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 145 | printComponent=true; | 151 | printComponent=true; | |
| 146 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 147 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 148 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 149 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 150 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 151 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 152 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 153 | } | 159 | } | |
| 154 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 155 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 156 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 157 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 158 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 159 | } | 165 | } | |
| 160 | else { | 166 | else { | |
| 161 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 162 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 163 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 164 | } | 170 | } | |
| 165 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 166 | } | 172 | } | |
| 167 | } | 173 | } | |
| 168 | } | 174 | } | |
| 169 | } | 175 | } | |
| 170 | if (printComponent) { | 176 | if (printComponent) { | |
| 171 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 172 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 173 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 174 | } | 180 | } | |
| 175 | } | 181 | } | |
| 176 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 177 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 178 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 179 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 180 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 181 | } | 187 | } | |
| 182 | } | 188 | } | |
| 183 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 184 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 185 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 186 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 187 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 188 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 189 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 190 | } | 196 | } | |
| 191 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 192 | } | 198 | } | |
| 193 | return result; | 199 | return result; | |
| 194 | } | 200 | } | |
| 195 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 196 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 197 | public void output(){ | 203 | public void output(){ | |
| 198 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 199 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 200 | } | 206 | } | |
| 201 | } | 207 | } | |
| 202 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 203 | return this; | 209 | return this; | |
| 204 | } | 210 | } | |
| 205 | public String toString(){ | 211 | public String toString(){ | |
| 206 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 207 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 208 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 209 | } | 215 | } | |
| 210 | return result.toString(); | 216 | return result.toString(); | |
| 211 | } | 217 | } | |
| 212 | } | 218 | } | |
| 213 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 214 | private Component component; | 220 | private Component component; | |
| 215 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 216 | this.component=component; | 222 | this.component=component; | |
| 217 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 218 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 219 | } | 225 | } | |
| 220 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 221 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 222 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 223 | } | 229 | } | |
| 224 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 225 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 226 | } | 232 | } | |
| 227 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 228 | if (state != null) { | 234 | if (state != null) { | |
| 229 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 230 | } | 236 | } | |
| 231 | return false; | 237 | return false; | |
| 232 | } | 238 | } | |
| 233 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 240 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 236 | } | 242 | } | |
| 237 | return false; | 243 | return false; | |
| 238 | } | 244 | } | |
| 239 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 240 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 241 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 242 | } | 248 | } | |
| 243 | return false; | 249 | return false; | |
| 244 | } | 250 | } | |
| 245 | private Logger logger; | 251 | private Logger logger; | |
| 246 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 247 | logger.add(s); | 253 | logger.add(s); | |
| 248 | } | 254 | } | |
| 249 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 250 | return logger; | 256 | return logger; | |
| 251 | } | 257 | } | |
| 252 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 253 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 254 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 255 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 256 | return onStart; | 262 | return onStart; | |
| 257 | } | 263 | } | |
| 258 | else { | 264 | else { | |
| 259 | return onStartCommand; | 265 | return onStartCommand; | |
| 260 | } | 266 | } | |
| 261 | } | 267 | } | |
| 262 | /** | 268 | /** | |
| 263 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 264 | */ | 270 | */ | |
| 265 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 266 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 267 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 268 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 269 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 270 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 271 | } | 277 | } | |
| 272 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 273 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 274 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 275 | } | 281 | } | |
| 276 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 277 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 278 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 279 | } | 285 | } | |
| 280 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 281 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 282 | if (weaklocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 288 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 283 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 284 | } | 290 | } | |
| 285 | } | 291 | } | |
| 286 | if (component.getComponentType().equals("Service")) { | 292 | if (component.getComponentType().equals("Service")) { | |
| 287 | SingleLockState onStartState=getServiceOnStart(); | 293 | SingleLockState onStartState=getServiceOnStart(); | |
| 288 | SingleLockState onDestroyState=map.get("onDestroy"); | 294 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 289 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 290 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 291 | } | 297 | } | |
| 292 | if (weakUnlocking(onDestroyState)) { | 298 | if (weakUnlocking(onDestroyState)) { | |
| 293 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 294 | } | 300 | } | |
| 295 | } | 301 | } | |
| 296 | if (component.getComponentType().equals("RunnableThread")) { | 302 | if (component.getComponentType().equals("RunnableThread")) { | |
| 297 | SingleLockState runState=map.get("run"); | 303 | SingleLockState runState=map.get("run"); | |
| 298 | if (locking(runState)) { | 304 | if (locking(runState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 300 | } | 306 | } | |
| 301 | } | 307 | } | |
| 302 | if (component.getComponentType().equals("Handler")) { | 308 | if (component.getComponentType().equals("Handler")) { | |
| 303 | SingleLockState handleState=map.get("handleMessage"); | 309 | SingleLockState handleState=map.get("handleMessage"); | |
| 304 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 306 | } | 312 | } | |
| 307 | } | 313 | } | |
| 308 | if (component.getComponentType().equals("BroadcastReceiver")) { | 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 309 | SingleLockState onReceiveState=map.get("onReceive"); | 315 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 310 | if (locking(onReceiveState)) { | 316 | if (locking(onReceiveState)) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 312 | } | 318 | } | |
| 313 | } | 319 | } | |
| 314 | } | 320 | } | |
| 315 | } | 321 | } | |
| 316 | } | 322 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_057 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_058 | |||
|---|---|---|---|---|
|
322 lines 12933 bytes Last modified : Mon May 14 23:48:04 2012 |
327 lines 13137 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:01.483 | 1 | //Time : 2012-04-24 19:08:30.329 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 1 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | INSERT IfStmt = 1 | |
| 8 | changes = 3 | |||
| 8 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | inserts = 1 | |||
| 9 | private/protected method declarations = 1 | 11 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 12 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 13 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 14 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 15 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 16 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 17 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 18 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 19 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 20 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 21 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 22 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 23 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 24 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 25 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 26 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 27 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 28 | public class AnalysisResults { | |
| 27 | /** | 29 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 30 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 31 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 32 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 33 | public class ComponentSummary { | |
| 32 | private Component component; | 34 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 35 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 36 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 37 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 38 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 39 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 40 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 41 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 42 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 43 | return allExitStates; | |
| 42 | } | 44 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 45 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 46 | allExitStates.put(n,st); | |
| 45 | } | 47 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 48 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 49 | callBackExitStates.put(cb,st); | |
| 48 | } | 50 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 51 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 52 | return allExitStates.get(method); | |
| 51 | } | 53 | } | |
| 52 | public String toString(){ | 54 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 55 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 56 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 57 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 58 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 59 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 60 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 61 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 62 | } | |
| 61 | } | 63 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 64 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 65 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 66 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 67 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 68 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 69 | String name=cb.getName(); | |
| 68 | ; | 70 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 71 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 72 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 73 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 74 | } | |
| 73 | } | 75 | } | |
| 74 | } | 76 | } | |
| 75 | } | 77 | } | |
| 76 | return null; | 78 | return null; | |
| 77 | } | 79 | } | |
| 78 | } | 80 | } | |
| 79 | public AnalysisResults(){ | 81 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 82 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 83 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 84 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 85 | /** | |
| 84 | * Invoke this after the component has been analyzed | 86 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 87 | * @param component | |
| 86 | */ | 88 | */ | |
| 87 | public void createComponentSummary( Component component){ | 89 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 90 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 91 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 92 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 93 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 94 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 95 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 96 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 97 | } | |
| 96 | } | 98 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 99 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 100 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 101 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 102 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 103 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 104 | return LockUsage.LOCKING; | |
| 103 | } | 105 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 106 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 107 | return LockUsage.EMPTY; | |
| 106 | } | 108 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 109 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 110 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 111 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 112 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 113 | return LockUsage.UNLOCKING; | |
| 112 | } | 114 | } | |
| 113 | else { | 115 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 116 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 117 | } | |
| 116 | } | 118 | } | |
| 117 | else { | 119 | else { | |
| 118 | return LockUsage.EMPTY; | 120 | return LockUsage.EMPTY; | |
| 119 | } | 121 | } | |
| 120 | } | 122 | } | |
| 121 | public ArrayList<String> processResults(){ | 123 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 124 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 125 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 126 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 127 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 128 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 129 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 130 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 131 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 132 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 133 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 134 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 135 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 136 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 137 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 138 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 139 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 140 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 141 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 142 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 143 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 144 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 145 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 146 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 147 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 148 | printMethod=true; | |
| 147 | } | 149 | } | |
| 148 | } | 150 | } | |
| 149 | if (printMethod) { | 151 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 152 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 153 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 154 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 155 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 157 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 158 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 159 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 160 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 161 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 162 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 163 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 164 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 165 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 166 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 167 | } | |
| 166 | else { | 168 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 169 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 170 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 171 | usageMap.put(lu,set); | |
| 170 | } | 172 | } | |
| 171 | policy.addFact(node,mergedLS); | 173 | policy.addFact(node,mergedLS); | |
| 172 | } | 174 | } | |
| 173 | } | 175 | } | |
| 174 | } | 176 | } | |
| 175 | } | 177 | } | |
| 176 | if (printComponent) { | 178 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 179 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 180 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 181 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 182 | } | |
| 181 | } | 183 | } | |
| 182 | System.out.println("==========================================\n"); | 184 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 185 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 186 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 187 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 188 | System.out.println(" " + s.toString()); | |
| 187 | } | 189 | } | |
| 188 | } | 190 | } | |
| 189 | System.out.println("==========================================\n"); | 191 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 192 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 193 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 194 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 195 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 196 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 197 | System.out.println("\n"); | |
| 196 | } | 198 | } | |
| 197 | result=logger.getStringList(); | 199 | result=logger.getStringList(); | |
| 198 | } | 200 | } | |
| 199 | return result; | 201 | return result; | |
| 200 | } | 202 | } | |
| 201 | public class Logger extends ArrayList<String> { | 203 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 204 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 205 | public void output(){ | |
| 204 | for ( String s : this) { | 206 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 207 | System.out.println(" " + s); | |
| 206 | } | 208 | } | |
| 207 | } | 209 | } | |
| 208 | public ArrayList<String> getStringList(){ | 210 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 211 | return this; | |
| 210 | } | 212 | } | |
| 211 | public String toString(){ | 213 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 214 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 215 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 216 | result.append(s + "\n"); | |
| 215 | } | 217 | } | |
| 216 | return result.toString(); | 218 | return result.toString(); | |
| 217 | } | 219 | } | |
| 218 | } | 220 | } | |
| 219 | public class ComponentPolicy { | 221 | public class ComponentPolicy { | |
| 220 | private Component component; | 222 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 223 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 224 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 225 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 226 | logger=new Logger(); | |
| 225 | } | 227 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 228 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 229 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 230 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 231 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 232 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 233 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 234 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 235 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 236 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 237 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 238 | } | |
| 237 | return false; | 239 | return false; | |
| 238 | } | 240 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 241 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 242 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 243 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 244 | } | |
| 243 | return false; | 245 | return false; | |
| 244 | } | 246 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 247 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 248 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 249 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 250 | } | |
| 249 | return false; | 251 | return false; | |
| 250 | } | 252 | } | |
| 251 | private Logger logger; | 253 | private Logger logger; | |
| 252 | private void logNote( String s){ | 254 | private void logNote( String s){ | |
| 253 | logger.add(s); | 255 | logger.add(s); | |
| 254 | } | 256 | } | |
| 255 | public Logger getLogger(){ | 257 | public Logger getLogger(){ | |
| 256 | return logger; | 258 | return logger; | |
| 257 | } | 259 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 260 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 261 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 262 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 263 | if (onStartCommand == null) { | |
| 262 | return onStart; | 264 | return onStart; | |
| 263 | } | 265 | } | |
| 264 | else { | 266 | else { | |
| 265 | return onStartCommand; | 267 | return onStartCommand; | |
| 266 | } | 268 | } | |
| 267 | } | 269 | } | |
| 268 | /** | 270 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 271 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 272 | */ | |
| 271 | public void solveFacts(){ | 273 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 274 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 275 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 276 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 277 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 278 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 279 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 280 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 281 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 282 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 283 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 284 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 285 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 286 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 287 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 288 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 289 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 290 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 291 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 292 | } | |
| 293 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |||
| 294 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |||
| 295 | } | |||
| 291 | } | 296 | } | |
| 292 | if (component.getComponentType().equals("Service")) { | 297 | if (component.getComponentType().equals("Service")) { | |
| 293 | SingleLockState onStartState=getServiceOnStart(); | 298 | SingleLockState onStartState=getServiceOnStart(); | |
| 294 | SingleLockState onDestroyState=map.get("onDestroy"); | 299 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 295 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 300 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 296 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 301 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 297 | } | 302 | } | |
| 298 | if (weakUnlocking(onDestroyState)) { | 303 | if (weakUnlocking(onDestroyState)) { | |
| 299 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 304 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 300 | } | 305 | } | |
| 301 | } | 306 | } | |
| 302 | if (component.getComponentType().equals("RunnableThread")) { | 307 | if (component.getComponentType().equals("RunnableThread")) { | |
| 303 | SingleLockState runState=map.get("run"); | 308 | SingleLockState runState=map.get("run"); | |
| 304 | if (locking(runState)) { | 309 | if (locking(runState)) { | |
| 305 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 306 | } | 311 | } | |
| 307 | } | 312 | } | |
| 308 | if (component.getComponentType().equals("Handler")) { | 313 | if (component.getComponentType().equals("Handler")) { | |
| 309 | SingleLockState handleState=map.get("handleMessage"); | 314 | SingleLockState handleState=map.get("handleMessage"); | |
| 310 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 315 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 311 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 316 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 312 | } | 317 | } | |
| 313 | } | 318 | } | |
| 314 | if (component.getComponentType().equals("BroadcastReceiver")) { | 319 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 315 | SingleLockState onReceiveState=map.get("onReceive"); | 320 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 316 | if (locking(onReceiveState)) { | 321 | if (locking(onReceiveState)) { | |
| 317 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 322 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 318 | } | 323 | } | |
| 319 | } | 324 | } | |
| 320 | } | 325 | } | |
| 321 | } | 326 | } | |
| 322 | } | 327 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_058 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_059 | |||
|---|---|---|---|---|
|
327 lines 13137 bytes Last modified : Mon May 14 23:48:04 2012 |
326 lines 13150 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:30.329 | 1 | //Time : 2012-04-24 19:08:35.198 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | INSERT IfStmt = 1 | 8 | changes = 5 | |
| 8 | changes = 3 | |||
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | inserts = 1 | |||
| 11 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 12 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 13 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 14 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 15 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 16 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 17 | import java.util.Map; | 16 | import java.util.Map; | |
| 18 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 19 | import java.util.Set; | 18 | import java.util.Set; | |
| 20 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 21 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 22 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 23 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 24 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 25 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 26 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 27 | import energy.util.E; | 26 | import energy.util.E; | |
| 28 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 29 | /** | 28 | /** | |
| 30 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 31 | */ | 30 | */ | |
| 32 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 33 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 34 | private Component component; | 33 | private Component component; | |
| 35 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 36 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 37 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 38 | this.component=c; | 37 | this.component=c; | |
| 39 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 40 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 41 | } | 40 | } | |
| 42 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 43 | return allExitStates; | 42 | return allExitStates; | |
| 44 | } | 43 | } | |
| 45 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 46 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 47 | } | 46 | } | |
| 48 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 49 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 50 | } | 49 | } | |
| 51 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 52 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 53 | } | 52 | } | |
| 54 | public String toString(){ | 53 | public String toString(){ | |
| 55 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 56 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 57 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 58 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 59 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 60 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 61 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 62 | } | 61 | } | |
| 63 | } | 62 | } | |
| 64 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 65 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 66 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 67 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 68 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 69 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 70 | ; | 69 | ; | |
| 71 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 72 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 73 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | } | 76 | } | |
| 78 | return null; | 77 | return null; | |
| 79 | } | 78 | } | |
| 80 | } | 79 | } | |
| 81 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 82 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 83 | } | 82 | } | |
| 84 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 85 | /** | 84 | /** | |
| 86 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 87 | * @param component | 86 | * @param component | |
| 88 | */ | 87 | */ | |
| 89 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 90 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 91 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 92 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 93 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 94 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 95 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 96 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 97 | } | 96 | } | |
| 98 | } | 97 | } | |
| 99 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 100 | } | 99 | } | |
| 101 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 102 | if (runState != null) { | 101 | if (runState != null) { | |
| 103 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 104 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 105 | } | 104 | } | |
| 106 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 107 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 108 | } | 107 | } | |
| 109 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 110 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 111 | } | 110 | } | |
| 112 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 113 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 114 | } | 113 | } | |
| 115 | else { | 114 | else { | |
| 116 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 117 | } | 116 | } | |
| 118 | } | 117 | } | |
| 119 | else { | 118 | else { | |
| 120 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 121 | } | 120 | } | |
| 122 | } | 121 | } | |
| 123 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 124 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 125 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 126 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 127 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 128 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 129 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 130 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 131 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 132 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 133 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 134 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 135 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 136 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 137 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 138 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 139 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 140 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 141 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 142 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 143 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 144 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 145 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 146 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 147 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 148 | printMethod=true; | 147 | printMethod=true; | |
| 149 | } | 148 | } | |
| 150 | } | 149 | } | |
| 151 | if (printMethod) { | 150 | if (printMethod) { | |
| 152 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 153 | printComponent=true; | 152 | printComponent=true; | |
| 154 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 155 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 157 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 158 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 159 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 160 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 161 | } | 160 | } | |
| 162 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 163 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 164 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 165 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 166 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 167 | } | 166 | } | |
| 168 | else { | 167 | else { | |
| 169 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 170 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 171 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 172 | } | 171 | } | |
| 173 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | } | 176 | } | |
| 178 | if (printComponent) { | 177 | if (printComponent) { | |
| 179 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 180 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 181 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 182 | } | 181 | } | |
| 183 | } | 182 | } | |
| 184 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 185 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 186 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 187 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 188 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 189 | } | 188 | } | |
| 190 | } | 189 | } | |
| 191 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 192 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 193 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 194 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 195 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 196 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 197 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 198 | } | 197 | } | |
| 199 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 200 | } | 199 | } | |
| 201 | return result; | 200 | return result; | |
| 202 | } | 201 | } | |
| 203 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 204 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 205 | public void output(){ | 204 | public void output(){ | |
| 206 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 207 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 208 | } | 207 | } | |
| 209 | } | 208 | } | |
| 210 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 211 | return this; | 210 | return this; | |
| 212 | } | 211 | } | |
| 213 | public String toString(){ | 212 | public String toString(){ | |
| 214 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 215 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 216 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 217 | } | 216 | } | |
| 218 | return result.toString(); | 217 | return result.toString(); | |
| 219 | } | 218 | } | |
| 220 | } | 219 | } | |
| 221 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 222 | private Component component; | 221 | private Component component; | |
| 223 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 224 | this.component=component; | 223 | this.component=component; | |
| 225 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 226 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 227 | } | 226 | } | |
| 228 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 229 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 230 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 231 | } | 230 | } | |
| 232 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 233 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 234 | } | 233 | } | |
| 235 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 236 | if (state != null) { | 235 | if (state != null) { | |
| 237 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 238 | } | 237 | } | |
| 239 | return false; | 238 | return false; | |
| 240 | } | 239 | } | |
| 241 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 242 | if (state != null) { | 241 | if (state != null) { | |
| 243 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 244 | } | 243 | } | |
| 245 | return false; | 244 | return false; | |
| 246 | } | 245 | } | |
| 247 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 248 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 249 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 250 | } | 249 | } | |
| 251 | return false; | 250 | return false; | |
| 252 | } | 251 | } | |
| 253 | private Logger logger; | 252 | private Logger logger; | |
| 254 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 255 | logger.add(s); | 254 | logger.add(s); | |
| 256 | } | 255 | } | |
| 257 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 258 | return logger; | 257 | return logger; | |
| 259 | } | 258 | } | |
| 260 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 261 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 262 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 263 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 264 | return onStart; | 263 | return onStart; | |
| 265 | } | 264 | } | |
| 266 | else { | 265 | else { | |
| 267 | return onStartCommand; | 266 | return onStartCommand; | |
| 268 | } | 267 | } | |
| 269 | } | 268 | } | |
| 270 | /** | 269 | /** | |
| 271 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 272 | */ | 271 | */ | |
| 273 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 274 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 275 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 276 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 277 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 278 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 279 | } | 278 | } | |
| 280 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 281 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 282 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 283 | } | 282 | } | |
| 284 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 285 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 286 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 287 | } | 286 | } | |
| 288 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 289 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 290 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 289 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 291 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 292 | } | 291 | } | |
| 293 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 292 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 294 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 293 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 295 | } | 294 | } | |
| 296 | } | 295 | } | |
| 297 | if (component.getComponentType().equals("Service")) { | 296 | if (component.getComponentType().equals("Service")) { | |
| 298 | SingleLockState onStartState=getServiceOnStart(); | 297 | SingleLockState onStartState=getServiceOnStart(); | |
| 299 | SingleLockState onDestroyState=map.get("onDestroy"); | 298 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 300 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 299 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 301 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 300 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 302 | } | 301 | } | |
| 303 | if (weakUnlocking(onDestroyState)) { | 302 | if (weakUnlocking(onDestroyState)) { | |
| 304 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 303 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 305 | } | 304 | } | |
| 306 | } | 305 | } | |
| 307 | if (component.getComponentType().equals("RunnableThread")) { | 306 | if (component.getComponentType().equals("RunnableThread")) { | |
| 308 | SingleLockState runState=map.get("run"); | 307 | SingleLockState runState=map.get("run"); | |
| 309 | if (locking(runState)) { | 308 | if (locking(runState)) { | |
| 310 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 309 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 311 | } | 310 | } | |
| 312 | } | 311 | } | |
| 313 | if (component.getComponentType().equals("Handler")) { | 312 | if (component.getComponentType().equals("Handler")) { | |
| 314 | SingleLockState handleState=map.get("handleMessage"); | 313 | SingleLockState handleState=map.get("handleMessage"); | |
| 315 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 314 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 316 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 315 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 317 | } | 316 | } | |
| 318 | } | 317 | } | |
| 319 | if (component.getComponentType().equals("BroadcastReceiver")) { | 318 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 320 | SingleLockState onReceiveState=map.get("onReceive"); | 319 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 321 | if (locking(onReceiveState)) { | 320 | if (locking(onReceiveState)) { | |
| 322 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 321 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 323 | } | 322 | } | |
| 324 | } | 323 | } | |
| 325 | } | 324 | } | |
| 326 | } | 325 | } | |
| 327 | } | 326 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_059 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_060 | |||
|---|---|---|---|---|
|
326 lines 13150 bytes Last modified : Mon May 14 23:48:04 2012 |
325 lines 13100 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:35.198 | 1 | //Time : 2012-04-24 19:08:39.016 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 7 | changes = 4 | |
| 9 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 15 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 17 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 25 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 28 | /** | 27 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 29 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 33 | private Component component; | 32 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 36 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 39 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 41 | return allExitStates; | |
| 43 | } | 42 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 46 | } | 45 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 49 | } | 48 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 52 | } | 51 | } | |
| 53 | public String toString(){ | 52 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 60 | } | |
| 62 | } | 61 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 69 | ; | 68 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 72 | } | |
| 74 | } | 73 | } | |
| 75 | } | 74 | } | |
| 76 | } | 75 | } | |
| 77 | return null; | 76 | return null; | |
| 78 | } | 77 | } | |
| 79 | } | 78 | } | |
| 80 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 81 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 83 | /** | |
| 85 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 85 | * @param component | |
| 87 | */ | 86 | */ | |
| 88 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 95 | } | |
| 97 | } | 96 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 98 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 100 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 104 | } | 103 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 107 | } | 106 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 109 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 113 | } | 112 | } | |
| 114 | else { | 113 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 115 | } | |
| 117 | } | 116 | } | |
| 118 | else { | 117 | else { | |
| 119 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 120 | } | 119 | } | |
| 121 | } | 120 | } | |
| 122 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 146 | printMethod=true; | |
| 148 | } | 147 | } | |
| 149 | } | 148 | } | |
| 150 | if (printMethod) { | 149 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 151 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 159 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 165 | } | |
| 167 | else { | 166 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 171 | } | 170 | } | |
| 172 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 173 | } | 172 | } | |
| 174 | } | 173 | } | |
| 175 | } | 174 | } | |
| 176 | } | 175 | } | |
| 177 | if (printComponent) { | 176 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 180 | } | |
| 182 | } | 181 | } | |
| 183 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 188 | } | 187 | } | |
| 189 | } | 188 | } | |
| 190 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 197 | } | 196 | } | |
| 198 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 199 | } | 198 | } | |
| 200 | return result; | 199 | return result; | |
| 201 | } | 200 | } | |
| 202 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 203 | public void output(){ | |
| 205 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 207 | } | 206 | } | |
| 208 | } | 207 | } | |
| 209 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 209 | return this; | |
| 211 | } | 210 | } | |
| 212 | public String toString(){ | 211 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 216 | } | 215 | } | |
| 217 | return result.toString(); | 216 | return result.toString(); | |
| 218 | } | 217 | } | |
| 219 | } | 218 | } | |
| 220 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 221 | private Component component; | 220 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 222 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 226 | } | 225 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 229 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 232 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 234 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 236 | } | |
| 238 | return false; | 237 | return false; | |
| 239 | } | 238 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 240 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 242 | } | |
| 244 | return false; | 243 | return false; | |
| 245 | } | 244 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 248 | } | |
| 250 | return false; | 249 | return false; | |
| 251 | } | 250 | } | |
| 252 | private Logger logger; | 251 | private Logger logger; | |
| 253 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 254 | logger.add(s); | 253 | logger.add(s); | |
| 255 | } | 254 | } | |
| 256 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 257 | return logger; | 256 | return logger; | |
| 258 | } | 257 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 263 | return onStart; | 262 | return onStart; | |
| 264 | } | 263 | } | |
| 265 | else { | 264 | else { | |
| 266 | return onStartCommand; | 265 | return onStartCommand; | |
| 267 | } | 266 | } | |
| 268 | } | 267 | } | |
| 269 | /** | 268 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 270 | */ | |
| 272 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 281 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 288 | if (unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 290 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 291 | } | 290 | } | |
| 292 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 293 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 294 | } | 293 | } | |
| 295 | } | 294 | } | |
| 296 | if (component.getComponentType().equals("Service")) { | 295 | if (component.getComponentType().equals("Service")) { | |
| 297 | SingleLockState onStartState=getServiceOnStart(); | 296 | SingleLockState onStartState=getServiceOnStart(); | |
| 298 | SingleLockState onDestroyState=map.get("onDestroy"); | 297 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 299 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 300 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 301 | } | 300 | } | |
| 302 | if (weakUnlocking(onDestroyState)) { | 301 | if (weakUnlocking(onDestroyState)) { | |
| 303 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 304 | } | 303 | } | |
| 305 | } | 304 | } | |
| 306 | if (component.getComponentType().equals("RunnableThread")) { | 305 | if (component.getComponentType().equals("RunnableThread")) { | |
| 307 | SingleLockState runState=map.get("run"); | 306 | SingleLockState runState=map.get("run"); | |
| 308 | if (locking(runState)) { | 307 | if (locking(runState)) { | |
| 309 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 310 | } | 309 | } | |
| 311 | } | 310 | } | |
| 312 | if (component.getComponentType().equals("Handler")) { | 311 | if (component.getComponentType().equals("Handler")) { | |
| 313 | SingleLockState handleState=map.get("handleMessage"); | 312 | SingleLockState handleState=map.get("handleMessage"); | |
| 314 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 315 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 316 | } | 315 | } | |
| 317 | } | 316 | } | |
| 318 | if (component.getComponentType().equals("BroadcastReceiver")) { | 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 319 | SingleLockState onReceiveState=map.get("onReceive"); | 318 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 320 | if (locking(onReceiveState)) { | 319 | if (locking(onReceiveState)) { | |
| 321 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 322 | } | 321 | } | |
| 323 | } | 322 | } | |
| 324 | } | 323 | } | |
| 325 | } | 324 | } | |
| 326 | } | 325 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_060 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_061 | |||
|---|---|---|---|---|
|
325 lines 13100 bytes Last modified : Mon May 14 23:48:04 2012 |
325 lines 13101 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:39.016 | 1 | //Time : 2012-04-24 19:08:45.830 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 288 | if (!unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("Service")) { | 295 | if (component.getComponentType().equals("Service")) { | |
| 296 | SingleLockState onStartState=getServiceOnStart(); | 296 | SingleLockState onStartState=getServiceOnStart(); | |
| 297 | SingleLockState onDestroyState=map.get("onDestroy"); | 297 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | if (weakUnlocking(onDestroyState)) { | 301 | if (weakUnlocking(onDestroyState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("RunnableThread")) { | 305 | if (component.getComponentType().equals("RunnableThread")) { | |
| 306 | SingleLockState runState=map.get("run"); | 306 | SingleLockState runState=map.get("run"); | |
| 307 | if (locking(runState)) { | 307 | if (locking(runState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | if (component.getComponentType().equals("Handler")) { | 311 | if (component.getComponentType().equals("Handler")) { | |
| 312 | SingleLockState handleState=map.get("handleMessage"); | 312 | SingleLockState handleState=map.get("handleMessage"); | |
| 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 318 | SingleLockState onReceiveState=map.get("onReceive"); | 318 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 319 | if (locking(onReceiveState)) { | 319 | if (locking(onReceiveState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_061 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_062 | |||
|---|---|---|---|---|
|
325 lines 13101 bytes Last modified : Mon May 14 23:48:04 2012 |
325 lines 13065 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:45.830 | 1 | //Time : 2012-04-24 19:08:51.193 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return false; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (!unlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 288 | if (!unlocking(onPauseState)) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("Service")) { | 295 | if (component.getComponentType().equals("Service")) { | |
| 296 | SingleLockState onStartState=getServiceOnStart(); | 296 | SingleLockState onStartState=getServiceOnStart(); | |
| 297 | SingleLockState onDestroyState=map.get("onDestroy"); | 297 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | if (weakUnlocking(onDestroyState)) { | 301 | if (weakUnlocking(onDestroyState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("RunnableThread")) { | 305 | if (component.getComponentType().equals("RunnableThread")) { | |
| 306 | SingleLockState runState=map.get("run"); | 306 | SingleLockState runState=map.get("run"); | |
| 307 | if (locking(runState)) { | 307 | if (locking(runState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | if (component.getComponentType().equals("Handler")) { | 311 | if (component.getComponentType().equals("Handler")) { | |
| 312 | SingleLockState handleState=map.get("handleMessage"); | 312 | SingleLockState handleState=map.get("handleMessage"); | |
| 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 318 | SingleLockState onReceiveState=map.get("onReceive"); | 318 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 319 | if (locking(onReceiveState)) { | 319 | if (locking(onReceiveState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_062 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_063 | |||
|---|---|---|---|---|
|
325 lines 13065 bytes Last modified : Mon May 14 23:48:04 2012 |
325 lines 13077 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:08:51.193 | 1 | //Time : 2012-04-24 19:09:14.993 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | |||
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 6 | CHANGE ReturnStmt to ReturnStmt = 1 | |
| 8 | changes to method solveFacts = 1 | 7 | changes = 3 | |
| 8 | changes to method strongUnlocking = 1 | |||
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return false; | 237 | return true; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return false; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (!unlocking(onPauseState)) { | 288 | if (!unlocking(onPauseState)) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("Service")) { | 295 | if (component.getComponentType().equals("Service")) { | |
| 296 | SingleLockState onStartState=getServiceOnStart(); | 296 | SingleLockState onStartState=getServiceOnStart(); | |
| 297 | SingleLockState onDestroyState=map.get("onDestroy"); | 297 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | if (weakUnlocking(onDestroyState)) { | 301 | if (weakUnlocking(onDestroyState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("RunnableThread")) { | 305 | if (component.getComponentType().equals("RunnableThread")) { | |
| 306 | SingleLockState runState=map.get("run"); | 306 | SingleLockState runState=map.get("run"); | |
| 307 | if (locking(runState)) { | 307 | if (locking(runState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | if (component.getComponentType().equals("Handler")) { | 311 | if (component.getComponentType().equals("Handler")) { | |
| 312 | SingleLockState handleState=map.get("handleMessage"); | 312 | SingleLockState handleState=map.get("handleMessage"); | |
| 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 318 | SingleLockState onReceiveState=map.get("onReceive"); | 318 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 319 | if (locking(onReceiveState)) { | 319 | if (locking(onReceiveState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_063 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_064 | |||
|---|---|---|---|---|
|
325 lines 13077 bytes Last modified : Mon May 14 23:48:04 2012 |
325 lines 13074 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:14.993 | 1 | //Time : 2012-04-24 19:09:18.874 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | CHANGE ReturnStmt to ReturnStmt = 1 | 6 | CHANGE ReturnStmt to ReturnStmt = 1 | |
| 7 | changes = 3 | 7 | changes = 3 | |
| 8 | changes to method strongUnlocking = 1 | 8 | changes to method weakUnlocking = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 25 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 27 | /** | 27 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 29 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 32 | private Component component; | 32 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 36 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 39 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 41 | return allExitStates; | |
| 42 | } | 42 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 45 | } | 45 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 48 | } | 48 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 51 | } | 51 | } | |
| 52 | public String toString(){ | 52 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 60 | } | |
| 61 | } | 61 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 68 | ; | 68 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | return null; | 76 | return null; | |
| 77 | } | 77 | } | |
| 78 | } | 78 | } | |
| 79 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 81 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 83 | /** | |
| 84 | * Invoke this after the component has been analyzed | 84 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 85 | * @param component | |
| 86 | */ | 86 | */ | |
| 87 | public void createComponentSummary( Component component){ | 87 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 88 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 90 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 92 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 94 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 95 | } | |
| 96 | } | 96 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 97 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 98 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 99 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 100 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 102 | return LockUsage.LOCKING; | |
| 103 | } | 103 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 105 | return LockUsage.EMPTY; | |
| 106 | } | 106 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 108 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 109 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 110 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 111 | return LockUsage.UNLOCKING; | |
| 112 | } | 112 | } | |
| 113 | else { | 113 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 114 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 115 | } | |
| 116 | } | 116 | } | |
| 117 | else { | 117 | else { | |
| 118 | return LockUsage.EMPTY; | 118 | return LockUsage.EMPTY; | |
| 119 | } | 119 | } | |
| 120 | } | 120 | } | |
| 121 | public ArrayList<String> processResults(){ | 121 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 122 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 123 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 127 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 128 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 129 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 130 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 131 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 133 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 135 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 136 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 137 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 140 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 141 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 143 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 144 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 145 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 146 | printMethod=true; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | if (printMethod) { | 149 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 151 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 155 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 156 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 159 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 161 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 162 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 163 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 164 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 165 | } | |
| 166 | else { | 166 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 168 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 169 | usageMap.put(lu,set); | |
| 170 | } | 170 | } | |
| 171 | policy.addFact(node,mergedLS); | 171 | policy.addFact(node,mergedLS); | |
| 172 | } | 172 | } | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | if (printComponent) { | 176 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 177 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 178 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 179 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 180 | } | |
| 181 | } | 181 | } | |
| 182 | System.out.println("==========================================\n"); | 182 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 183 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 184 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 186 | System.out.println(" " + s.toString()); | |
| 187 | } | 187 | } | |
| 188 | } | 188 | } | |
| 189 | System.out.println("==========================================\n"); | 189 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 190 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 191 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 192 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 193 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 194 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 195 | System.out.println("\n"); | |
| 196 | } | 196 | } | |
| 197 | result=logger.getStringList(); | 197 | result=logger.getStringList(); | |
| 198 | } | 198 | } | |
| 199 | return result; | 199 | return result; | |
| 200 | } | 200 | } | |
| 201 | public class Logger extends ArrayList<String> { | 201 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 202 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 203 | public void output(){ | |
| 204 | for ( String s : this) { | 204 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 205 | System.out.println(" " + s); | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | public ArrayList<String> getStringList(){ | 208 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 209 | return this; | |
| 210 | } | 210 | } | |
| 211 | public String toString(){ | 211 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 212 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 213 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 214 | result.append(s + "\n"); | |
| 215 | } | 215 | } | |
| 216 | return result.toString(); | 216 | return result.toString(); | |
| 217 | } | 217 | } | |
| 218 | } | 218 | } | |
| 219 | public class ComponentPolicy { | 219 | public class ComponentPolicy { | |
| 220 | private Component component; | 220 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 221 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 222 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 223 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 224 | logger=new Logger(); | |
| 225 | } | 225 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 226 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 227 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 228 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 229 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 230 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 231 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 232 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 233 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 234 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 236 | } | |
| 237 | return true; | 237 | return true; | |
| 238 | } | 238 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 239 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 240 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 242 | } | |
| 243 | return false; | 243 | return true; | |
| 244 | } | 244 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 245 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 246 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 248 | } | |
| 249 | return false; | 249 | return false; | |
| 250 | } | 250 | } | |
| 251 | private Logger logger; | 251 | private Logger logger; | |
| 252 | private void logNote( String s){ | 252 | private void logNote( String s){ | |
| 253 | logger.add(s); | 253 | logger.add(s); | |
| 254 | } | 254 | } | |
| 255 | public Logger getLogger(){ | 255 | public Logger getLogger(){ | |
| 256 | return logger; | 256 | return logger; | |
| 257 | } | 257 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 258 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 259 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 261 | if (onStartCommand == null) { | |
| 262 | return onStart; | 262 | return onStart; | |
| 263 | } | 263 | } | |
| 264 | else { | 264 | else { | |
| 265 | return onStartCommand; | 265 | return onStartCommand; | |
| 266 | } | 266 | } | |
| 267 | } | 267 | } | |
| 268 | /** | 268 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 269 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 270 | */ | |
| 271 | public void solveFacts(){ | 271 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 272 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 277 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 281 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 285 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (!unlocking(onPauseState)) { | 288 | if (!unlocking(onPauseState)) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | |
| 290 | } | 290 | } | |
| 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 293 | } | 293 | } | |
| 294 | } | 294 | } | |
| 295 | if (component.getComponentType().equals("Service")) { | 295 | if (component.getComponentType().equals("Service")) { | |
| 296 | SingleLockState onStartState=getServiceOnStart(); | 296 | SingleLockState onStartState=getServiceOnStart(); | |
| 297 | SingleLockState onDestroyState=map.get("onDestroy"); | 297 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 300 | } | 300 | } | |
| 301 | if (weakUnlocking(onDestroyState)) { | 301 | if (weakUnlocking(onDestroyState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 303 | } | 303 | } | |
| 304 | } | 304 | } | |
| 305 | if (component.getComponentType().equals("RunnableThread")) { | 305 | if (component.getComponentType().equals("RunnableThread")) { | |
| 306 | SingleLockState runState=map.get("run"); | 306 | SingleLockState runState=map.get("run"); | |
| 307 | if (locking(runState)) { | 307 | if (locking(runState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 309 | } | 309 | } | |
| 310 | } | 310 | } | |
| 311 | if (component.getComponentType().equals("Handler")) { | 311 | if (component.getComponentType().equals("Handler")) { | |
| 312 | SingleLockState handleState=map.get("handleMessage"); | 312 | SingleLockState handleState=map.get("handleMessage"); | |
| 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 315 | } | 315 | } | |
| 316 | } | 316 | } | |
| 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 318 | SingleLockState onReceiveState=map.get("onReceive"); | 318 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 319 | if (locking(onReceiveState)) { | 319 | if (locking(onReceiveState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 321 | } | 321 | } | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_064 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_065 | |||
|---|---|---|---|---|
|
325 lines 13074 bytes Last modified : Mon May 14 23:48:04 2012 |
326 lines 13098 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:18.874 | 1 | //Time : 2012-04-24 19:09:52.799 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | CHANGE ReturnStmt to ReturnStmt = 1 | 8 | changes = 5 | |
| 7 | changes = 3 | 9 | changes to method solveFacts = 1 | |
| 8 | changes to method weakUnlocking = 1 | |||
| 9 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 16 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 18 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 25 | import energy.util.E; | 26 | import energy.util.E; | |
| 26 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 27 | /** | 28 | /** | |
| 28 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 29 | */ | 30 | */ | |
| 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 31 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 32 | private Component component; | 33 | private Component component; | |
| 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 35 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 36 | this.component=c; | 37 | this.component=c; | |
| 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 39 | } | 40 | } | |
| 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 41 | return allExitStates; | 42 | return allExitStates; | |
| 42 | } | 43 | } | |
| 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 44 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 45 | } | 46 | } | |
| 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 47 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 48 | } | 49 | } | |
| 49 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 50 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 51 | } | 52 | } | |
| 52 | public String toString(){ | 53 | public String toString(){ | |
| 53 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 55 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 56 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 57 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 58 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 59 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 60 | } | 61 | } | |
| 61 | } | 62 | } | |
| 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 63 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 64 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 65 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 66 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 67 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 68 | ; | 69 | ; | |
| 69 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 70 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 72 | } | 73 | } | |
| 73 | } | 74 | } | |
| 74 | } | 75 | } | |
| 75 | } | 76 | } | |
| 76 | return null; | 77 | return null; | |
| 77 | } | 78 | } | |
| 78 | } | 79 | } | |
| 79 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 81 | } | 82 | } | |
| 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 83 | /** | 84 | /** | |
| 84 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 85 | * @param component | 86 | * @param component | |
| 86 | */ | 87 | */ | |
| 87 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 88 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 89 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 90 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 91 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 92 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 93 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 94 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 95 | } | 96 | } | |
| 96 | } | 97 | } | |
| 97 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 98 | } | 99 | } | |
| 99 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 100 | if (runState != null) { | 101 | if (runState != null) { | |
| 101 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 102 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 103 | } | 104 | } | |
| 104 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 105 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 106 | } | 107 | } | |
| 107 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 108 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 109 | } | 110 | } | |
| 110 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 111 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 112 | } | 113 | } | |
| 113 | else { | 114 | else { | |
| 114 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 115 | } | 116 | } | |
| 116 | } | 117 | } | |
| 117 | else { | 118 | else { | |
| 118 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 119 | } | 120 | } | |
| 120 | } | 121 | } | |
| 121 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 122 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 123 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 124 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 125 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 126 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 127 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 128 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 129 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 130 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 131 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 132 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 133 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 134 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 135 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 136 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 137 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 138 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 139 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 140 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 141 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 142 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 143 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 144 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 145 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 146 | printMethod=true; | 147 | printMethod=true; | |
| 147 | } | 148 | } | |
| 148 | } | 149 | } | |
| 149 | if (printMethod) { | 150 | if (printMethod) { | |
| 150 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 151 | printComponent=true; | 152 | printComponent=true; | |
| 152 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 153 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 154 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 155 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 156 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 157 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 158 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 159 | } | 160 | } | |
| 160 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 161 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 162 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 163 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 164 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 165 | } | 166 | } | |
| 166 | else { | 167 | else { | |
| 167 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 168 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 169 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 170 | } | 171 | } | |
| 171 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 172 | } | 173 | } | |
| 173 | } | 174 | } | |
| 174 | } | 175 | } | |
| 175 | } | 176 | } | |
| 176 | if (printComponent) { | 177 | if (printComponent) { | |
| 177 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 178 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 179 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 180 | } | 181 | } | |
| 181 | } | 182 | } | |
| 182 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 183 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 184 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 185 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 186 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 187 | } | 188 | } | |
| 188 | } | 189 | } | |
| 189 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 190 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 191 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 192 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 193 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 194 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 195 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 196 | } | 197 | } | |
| 197 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 198 | } | 199 | } | |
| 199 | return result; | 200 | return result; | |
| 200 | } | 201 | } | |
| 201 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 202 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 203 | public void output(){ | 204 | public void output(){ | |
| 204 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 205 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 206 | } | 207 | } | |
| 207 | } | 208 | } | |
| 208 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 209 | return this; | 210 | return this; | |
| 210 | } | 211 | } | |
| 211 | public String toString(){ | 212 | public String toString(){ | |
| 212 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 213 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 214 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 215 | } | 216 | } | |
| 216 | return result.toString(); | 217 | return result.toString(); | |
| 217 | } | 218 | } | |
| 218 | } | 219 | } | |
| 219 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 220 | private Component component; | 221 | private Component component; | |
| 221 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 222 | this.component=component; | 223 | this.component=component; | |
| 223 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 224 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 225 | } | 226 | } | |
| 226 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 227 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 228 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 229 | } | 230 | } | |
| 230 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 231 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 232 | } | 233 | } | |
| 233 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 234 | if (state != null) { | 235 | if (state != null) { | |
| 235 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 236 | } | 237 | } | |
| 237 | return true; | 238 | return true; | |
| 238 | } | 239 | } | |
| 239 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 240 | if (state != null) { | 241 | if (state != null) { | |
| 241 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 242 | } | 243 | } | |
| 243 | return true; | 244 | return true; | |
| 244 | } | 245 | } | |
| 245 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 246 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 247 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 248 | } | 249 | } | |
| 249 | return false; | 250 | return false; | |
| 250 | } | 251 | } | |
| 251 | private Logger logger; | 252 | private Logger logger; | |
| 252 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 253 | logger.add(s); | 254 | logger.add(s); | |
| 254 | } | 255 | } | |
| 255 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 256 | return logger; | 257 | return logger; | |
| 257 | } | 258 | } | |
| 258 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 259 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 260 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 261 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 262 | return onStart; | 263 | return onStart; | |
| 263 | } | 264 | } | |
| 264 | else { | 265 | else { | |
| 265 | return onStartCommand; | 266 | return onStartCommand; | |
| 266 | } | 267 | } | |
| 267 | } | 268 | } | |
| 268 | /** | 269 | /** | |
| 269 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 270 | */ | 271 | */ | |
| 271 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 272 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 273 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 277 | } | 278 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 281 | } | 282 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 285 | } | 286 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 288 | if (!unlocking(onPauseState)) { | 289 | if (!unlocking(onPauseState)) { | |
| 289 | logNote("STRONG BUG: onPause - onResume (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | |
| 290 | } | 291 | } | |
| 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 292 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 292 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 293 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | |
| 293 | } | 294 | } | |
| 294 | } | 295 | } | |
| 295 | if (component.getComponentType().equals("Service")) { | 296 | if (component.getComponentType().equals("Service")) { | |
| 296 | SingleLockState onStartState=getServiceOnStart(); | 297 | SingleLockState onStartState=getServiceOnStart(); | |
| 297 | SingleLockState onDestroyState=map.get("onDestroy"); | 298 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 299 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 300 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 300 | } | 301 | } | |
| 301 | if (weakUnlocking(onDestroyState)) { | 302 | if (weakUnlocking(onDestroyState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 303 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 303 | } | 304 | } | |
| 304 | } | 305 | } | |
| 305 | if (component.getComponentType().equals("RunnableThread")) { | 306 | if (component.getComponentType().equals("RunnableThread")) { | |
| 306 | SingleLockState runState=map.get("run"); | 307 | SingleLockState runState=map.get("run"); | |
| 307 | if (locking(runState)) { | 308 | if (locking(runState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 309 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 309 | } | 310 | } | |
| 310 | } | 311 | } | |
| 311 | if (component.getComponentType().equals("Handler")) { | 312 | if (component.getComponentType().equals("Handler")) { | |
| 312 | SingleLockState handleState=map.get("handleMessage"); | 313 | SingleLockState handleState=map.get("handleMessage"); | |
| 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 314 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 315 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 315 | } | 316 | } | |
| 316 | } | 317 | } | |
| 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | 318 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 318 | SingleLockState onReceiveState=map.get("onReceive"); | 319 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 319 | if (locking(onReceiveState)) { | 320 | if (locking(onReceiveState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 321 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 321 | } | 322 | } | |
| 322 | } | 323 | } | |
| 323 | } | 324 | } | |
| 324 | } | 325 | } | |
| 325 | } | 326 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_065 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_066 | |||
|---|---|---|---|---|
|
326 lines 13098 bytes Last modified : Mon May 14 23:48:04 2012 |
326 lines 13087 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:52.799 | 1 | //Time : 2012-04-24 19:09:55.740 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |
| 6 | CHANGE IfStmt to IfStmt = 2 | 6 | CHANGE IfStmt to IfStmt = 2 | |
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 8 | changes = 5 | |
| 9 | changes to method solveFacts = 1 | 9 | changes to method solveFacts = 1 | |
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return true; | 238 | return true; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return true; | 244 | return true; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | 273 | E.log(1,"Looking for: " + component.getComponentType()); | |
| 274 | if (component.getComponentType().equals("Activity")) { | 274 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 275 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 276 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 278 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 279 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 280 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 282 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 283 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 284 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 286 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 287 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 288 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (!unlocking(onPauseState)) { | 289 | if (!unlocking(onPauseState)) { | |
| 290 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | 290 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | |
| 291 | } | 291 | } | |
| 292 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 292 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 293 | logNote("WEAK BUG: onPause - onResume (" + component.toString() + ")"); | 293 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | |
| 294 | } | 294 | } | |
| 295 | } | 295 | } | |
| 296 | if (component.getComponentType().equals("Service")) { | 296 | if (component.getComponentType().equals("Service")) { | |
| 297 | SingleLockState onStartState=getServiceOnStart(); | 297 | SingleLockState onStartState=getServiceOnStart(); | |
| 298 | SingleLockState onDestroyState=map.get("onDestroy"); | 298 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 299 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 299 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 300 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 300 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 301 | } | 301 | } | |
| 302 | if (weakUnlocking(onDestroyState)) { | 302 | if (weakUnlocking(onDestroyState)) { | |
| 303 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 303 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 304 | } | 304 | } | |
| 305 | } | 305 | } | |
| 306 | if (component.getComponentType().equals("RunnableThread")) { | 306 | if (component.getComponentType().equals("RunnableThread")) { | |
| 307 | SingleLockState runState=map.get("run"); | 307 | SingleLockState runState=map.get("run"); | |
| 308 | if (locking(runState)) { | 308 | if (locking(runState)) { | |
| 309 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 309 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 310 | } | 310 | } | |
| 311 | } | 311 | } | |
| 312 | if (component.getComponentType().equals("Handler")) { | 312 | if (component.getComponentType().equals("Handler")) { | |
| 313 | SingleLockState handleState=map.get("handleMessage"); | 313 | SingleLockState handleState=map.get("handleMessage"); | |
| 314 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 314 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 315 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 315 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 316 | } | 316 | } | |
| 317 | } | 317 | } | |
| 318 | if (component.getComponentType().equals("BroadcastReceiver")) { | 318 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 319 | SingleLockState onReceiveState=map.get("onReceive"); | 319 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 320 | if (locking(onReceiveState)) { | 320 | if (locking(onReceiveState)) { | |
| 321 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 321 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 322 | } | 322 | } | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } | |
| 326 | } | 326 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_066 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_067 | |||
|---|---|---|---|---|
|
326 lines 13087 bytes Last modified : Mon May 14 23:48:04 2012 |
325 lines 12987 bytes Last modified : Mon May 14 23:48:04 2012 |
|||
| 1 | //Time : 2012-04-24 19:09:55.740 | 1 | //Time : 2012-04-24 19:43:38.605 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt to ExpressionStmt = 1 | |||
| 6 | CHANGE IfStmt to IfStmt = 2 | |||
| 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | changes = 5 | 6 | DELETE ExpressionStmt = 1 | |
| 7 | changes = 2 | |||
| 9 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | deletes = 1 | |||
| 10 | private/protected method declarations = 1 | 10 | private/protected method declarations = 1 | |
| 11 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 12 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 16 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 18 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | 26 | import energy.util.E; | |
| 27 | public class AnalysisResults { | 27 | public class AnalysisResults { | |
| 28 | /** | 28 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 29 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 30 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 32 | public class ComponentSummary { | |
| 33 | private Component component; | 33 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 36 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 37 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 40 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 42 | return allExitStates; | |
| 43 | } | 43 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 45 | allExitStates.put(n,st); | |
| 46 | } | 46 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 48 | callBackExitStates.put(cb,st); | |
| 49 | } | 49 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 50 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 51 | return allExitStates.get(method); | |
| 52 | } | 52 | } | |
| 53 | public String toString(){ | 53 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 54 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 56 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 57 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 58 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 59 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 60 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 61 | } | |
| 62 | } | 62 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 64 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 65 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 66 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 67 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 68 | String name=cb.getName(); | |
| 69 | ; | 69 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 70 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 71 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | } | 76 | } | |
| 77 | return null; | 77 | return null; | |
| 78 | } | 78 | } | |
| 79 | } | 79 | } | |
| 80 | public AnalysisResults(){ | 80 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 82 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 84 | /** | 84 | /** | |
| 85 | * Invoke this after the component has been analyzed | 85 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 86 | * @param component | |
| 87 | */ | 87 | */ | |
| 88 | public void createComponentSummary( Component component){ | 88 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 89 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 91 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 93 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 95 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 96 | } | |
| 97 | } | 97 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 98 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 99 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 100 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 101 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 103 | return LockUsage.LOCKING; | |
| 104 | } | 104 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 106 | return LockUsage.EMPTY; | |
| 107 | } | 107 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 109 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 110 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 111 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 112 | return LockUsage.UNLOCKING; | |
| 113 | } | 113 | } | |
| 114 | else { | 114 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 115 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 116 | } | |
| 117 | } | 117 | } | |
| 118 | else { | 118 | else { | |
| 119 | return LockUsage.EMPTY; | 119 | return LockUsage.EMPTY; | |
| 120 | } | 120 | } | |
| 121 | } | 121 | } | |
| 122 | public ArrayList<String> processResults(){ | 122 | public ArrayList<String> processResults(){ | |
| 123 | ArrayList<String> result=null; | 123 | ArrayList<String> result=null; | |
| 124 | System.out.println("\n=========================================="); | 124 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 128 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 129 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 130 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 131 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 132 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 134 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 136 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 137 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 138 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 141 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 142 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 144 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 145 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 146 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 147 | printMethod=true; | |
| 148 | } | 148 | } | |
| 149 | } | 149 | } | |
| 150 | if (printMethod) { | 150 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 152 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 156 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 157 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 160 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 162 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 163 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 164 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 165 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 166 | } | |
| 167 | else { | 167 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 169 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 170 | usageMap.put(lu,set); | |
| 171 | } | 171 | } | |
| 172 | policy.addFact(node,mergedLS); | 172 | policy.addFact(node,mergedLS); | |
| 173 | } | 173 | } | |
| 174 | } | 174 | } | |
| 175 | } | 175 | } | |
| 176 | } | 176 | } | |
| 177 | if (printComponent) { | 177 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 178 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 179 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 180 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 181 | } | |
| 182 | } | 182 | } | |
| 183 | System.out.println("==========================================\n"); | 183 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 184 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 185 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 187 | System.out.println(" " + s.toString()); | |
| 188 | } | 188 | } | |
| 189 | } | 189 | } | |
| 190 | System.out.println("==========================================\n"); | 190 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 191 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 192 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 193 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 195 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 196 | System.out.println("\n"); | |
| 197 | } | 197 | } | |
| 198 | result=logger.getStringList(); | 198 | result=logger.getStringList(); | |
| 199 | } | 199 | } | |
| 200 | return result; | 200 | return result; | |
| 201 | } | 201 | } | |
| 202 | public class Logger extends ArrayList<String> { | 202 | public class Logger extends ArrayList<String> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 203 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 204 | public void output(){ | |
| 205 | for ( String s : this) { | 205 | for ( String s : this) { | |
| 206 | System.out.println(" " + s); | 206 | System.out.println(" " + s); | |
| 207 | } | 207 | } | |
| 208 | } | 208 | } | |
| 209 | public ArrayList<String> getStringList(){ | 209 | public ArrayList<String> getStringList(){ | |
| 210 | return this; | 210 | return this; | |
| 211 | } | 211 | } | |
| 212 | public String toString(){ | 212 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 213 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 214 | for ( String s : this) { | |
| 215 | result.append(s + "\n"); | 215 | result.append(s + "\n"); | |
| 216 | } | 216 | } | |
| 217 | return result.toString(); | 217 | return result.toString(); | |
| 218 | } | 218 | } | |
| 219 | } | 219 | } | |
| 220 | public class ComponentPolicy { | 220 | public class ComponentPolicy { | |
| 221 | private Component component; | 221 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 222 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 223 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 224 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 225 | logger=new Logger(); | |
| 226 | } | 226 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 227 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 228 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 229 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 230 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 231 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 232 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 233 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 234 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 235 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 237 | } | |
| 238 | return true; | 238 | return true; | |
| 239 | } | 239 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 240 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 241 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 243 | } | |
| 244 | return true; | 244 | return true; | |
| 245 | } | 245 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 246 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 247 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 249 | } | |
| 250 | return false; | 250 | return false; | |
| 251 | } | 251 | } | |
| 252 | private Logger logger; | 252 | private Logger logger; | |
| 253 | private void logNote( String s){ | 253 | private void logNote( String s){ | |
| 254 | logger.add(s); | 254 | logger.add(s); | |
| 255 | } | 255 | } | |
| 256 | public Logger getLogger(){ | 256 | public Logger getLogger(){ | |
| 257 | return logger; | 257 | return logger; | |
| 258 | } | 258 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 259 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 260 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 262 | if (onStartCommand == null) { | |
| 263 | return onStart; | 263 | return onStart; | |
| 264 | } | 264 | } | |
| 265 | else { | 265 | else { | |
| 266 | return onStartCommand; | 266 | return onStartCommand; | |
| 267 | } | 267 | } | |
| 268 | } | 268 | } | |
| 269 | /** | 269 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 270 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 271 | */ | |
| 272 | public void solveFacts(){ | 272 | public void solveFacts(){ | |
| 273 | E.log(1,"Looking for: " + component.getComponentType()); | |||
| 274 | if (component.getComponentType().equals("Activity")) { | 273 | if (component.getComponentType().equals("Activity")) { | |
| 275 | SingleLockState onCreateState=map.get("onCreate"); | 274 | SingleLockState onCreateState=map.get("onCreate"); | |
| 276 | if (locking(onCreateState)) { | 275 | if (locking(onCreateState)) { | |
| 277 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | |
| 278 | } | 277 | } | |
| 279 | SingleLockState onStartState=map.get("onStart"); | 278 | SingleLockState onStartState=map.get("onStart"); | |
| 280 | if (locking(onStartState)) { | 279 | if (locking(onStartState)) { | |
| 281 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | |
| 282 | } | 281 | } | |
| 283 | SingleLockState onRestartState=map.get("onRestart"); | 282 | SingleLockState onRestartState=map.get("onRestart"); | |
| 284 | if (locking(onRestartState)) { | 283 | if (locking(onRestartState)) { | |
| 285 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | |
| 286 | } | 285 | } | |
| 287 | SingleLockState onPauseState=map.get("onPause"); | 286 | SingleLockState onPauseState=map.get("onPause"); | |
| 288 | SingleLockState onResumeState=map.get("onResume"); | 287 | SingleLockState onResumeState=map.get("onResume"); | |
| 289 | if (!unlocking(onPauseState)) { | 288 | if (!unlocking(onPauseState)) { | |
| 290 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | 289 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | |
| 291 | } | 290 | } | |
| 292 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 293 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | 292 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | |
| 294 | } | 293 | } | |
| 295 | } | 294 | } | |
| 296 | if (component.getComponentType().equals("Service")) { | 295 | if (component.getComponentType().equals("Service")) { | |
| 297 | SingleLockState onStartState=getServiceOnStart(); | 296 | SingleLockState onStartState=getServiceOnStart(); | |
| 298 | SingleLockState onDestroyState=map.get("onDestroy"); | 297 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 299 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 300 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | |
| 301 | } | 300 | } | |
| 302 | if (weakUnlocking(onDestroyState)) { | 301 | if (weakUnlocking(onDestroyState)) { | |
| 303 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | |
| 304 | } | 303 | } | |
| 305 | } | 304 | } | |
| 306 | if (component.getComponentType().equals("RunnableThread")) { | 305 | if (component.getComponentType().equals("RunnableThread")) { | |
| 307 | SingleLockState runState=map.get("run"); | 306 | SingleLockState runState=map.get("run"); | |
| 308 | if (locking(runState)) { | 307 | if (locking(runState)) { | |
| 309 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | |
| 310 | } | 309 | } | |
| 311 | } | 310 | } | |
| 312 | if (component.getComponentType().equals("Handler")) { | 311 | if (component.getComponentType().equals("Handler")) { | |
| 313 | SingleLockState handleState=map.get("handleMessage"); | 312 | SingleLockState handleState=map.get("handleMessage"); | |
| 314 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 315 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | |
| 316 | } | 315 | } | |
| 317 | } | 316 | } | |
| 318 | if (component.getComponentType().equals("BroadcastReceiver")) { | 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 319 | SingleLockState onReceiveState=map.get("onReceive"); | 318 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 320 | if (locking(onReceiveState)) { | 319 | if (locking(onReceiveState)) { | |
| 321 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | |
| 322 | } | 321 | } | |
| 323 | } | 322 | } | |
| 324 | } | 323 | } | |
| 325 | } | 324 | } | |
| 326 | } | 325 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_067 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_068 | |||
|---|---|---|---|---|
|
325 lines 12987 bytes Last modified : Mon May 14 23:48:04 2012 |
333 lines 13323 bytes Last modified : Mon May 14 23:48:11 2012 |
|||
| 1 | //Time : 2012-04-24 19:43:38.605 | 1 | //Time : 2012-04-26 18:50:13.586 | |
| 2 | //Files Open : /com.ibm.wala.core/src/com/ibm/wala/cfg/ShrikeCFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/AbstractCFG.java /com.ibm.wala.core/src/com/ibm/wala/ssa/SSACFG.java /com.ibm.wala.core/src/com/ibm/wala/cfg/ControlFlowGraph.java /pvekris/src/main/java/energy/analysis/AnalysisResults.java /com.ibm.wala.core/src/com/ibm/wala/cfg/CFGSanitizer.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | package energy.analysis; | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 6 | DELETE ExpressionStmt = 1 | |||
| 7 | changes = 2 | |||
| 8 | changes to method solveFacts = 1 | |||
| 9 | deletes = 1 | |||
| 10 | private/protected method declarations = 1 | |||
| 11 | */package energy.analysis; | |||
| 12 | import java.util.ArrayList; | 4 | import java.util.ArrayList; | |
| 13 | import java.util.HashMap; | 5 | import java.util.HashMap; | |
| 14 | import java.util.HashSet; | 6 | import java.util.HashSet; | |
| 15 | import java.util.Iterator; | 7 | import java.util.Iterator; | |
| 16 | import java.util.Map; | 8 | import java.util.Map; | |
| 17 | import java.util.Map.Entry; | 9 | import java.util.Map.Entry; | |
| 18 | import java.util.Set; | 10 | import java.util.Set; | |
| 19 | import com.ibm.wala.ipa.callgraph.CGNode; | 11 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 20 | import com.ibm.wala.util.collections.Pair; | 12 | import com.ibm.wala.util.collections.Pair; | |
| 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 22 | import energy.components.Component; | 14 | import energy.components.Component; | |
| 23 | import energy.components.Component.CallBack; | 15 | import energy.components.Component.CallBack; | |
| 24 | import energy.interproc.CompoundLockState; | 16 | import energy.interproc.CompoundLockState; | |
| 25 | import energy.interproc.SingleLockState; | 17 | import energy.interproc.SingleLockState; | |
| 26 | import energy.util.E; | |||
| 27 | public class AnalysisResults { | 18 | public class AnalysisResults { | |
| 28 | /** | 19 | /** | |
| 29 | * Main structures that hold the analysis results for every component | 20 | * Main structures that hold the analysis results for every component | |
| 30 | */ | 21 | */ | |
| 31 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 32 | public class ComponentSummary { | 23 | public class ComponentSummary { | |
| 33 | private Component component; | 24 | private Component component; | |
| 34 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 35 | private HashMap<CGNode,CompoundLockState> allExitStates; | 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 36 | public ComponentSummary( Component c){ | 27 | public ComponentSummary( Component c){ | |
| 37 | this.component=c; | 28 | this.component=c; | |
| 38 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 39 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 40 | } | 31 | } | |
| 41 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 42 | return allExitStates; | 33 | return allExitStates; | |
| 43 | } | 34 | } | |
| 44 | public void registerNodeState( CGNode n, CompoundLockState st){ | 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 45 | allExitStates.put(n,st); | 36 | allExitStates.put(n,st); | |
| 46 | } | 37 | } | |
| 47 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 48 | callBackExitStates.put(cb,st); | 39 | callBackExitStates.put(cb,st); | |
| 49 | } | 40 | } | |
| 50 | public CompoundLockState getStateForMethod( String method){ | 41 | public CompoundLockState getStateForMethod( String method){ | |
| 51 | return allExitStates.get(method); | 42 | return allExitStates.get(method); | |
| 52 | } | 43 | } | |
| 53 | public String toString(){ | 44 | public String toString(){ | |
| 54 | StringBuffer sb=new StringBuffer(); | 45 | StringBuffer sb=new StringBuffer(); | |
| 55 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 56 | CGNode next=it.next(); | 47 | CGNode next=it.next(); | |
| 57 | String name=next.getMethod().getName().toString(); | 48 | String name=next.getMethod().getName().toString(); | |
| 58 | CompoundLockState stateForMethod=getStateForMethod(name); | 49 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 59 | if (stateForMethod != null) { | 50 | if (stateForMethod != null) { | |
| 60 | sb.append(name + ":\n" + stateForMethod.toString()); | 51 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 61 | } | 52 | } | |
| 62 | } | 53 | } | |
| 63 | HashSet<CallBack> callbacks=component.getCallbacks(); | 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 64 | if (callbacks != null) { | 55 | if (callbacks != null) { | |
| 65 | if (callbacks.size() > 0) { | 56 | if (callbacks.size() > 0) { | |
| 66 | sb.append("Callbacks:\n"); | 57 | sb.append("Callbacks:\n"); | |
| 67 | for ( CallBack cb : callbacks) { | 58 | for ( CallBack cb : callbacks) { | |
| 68 | String name=cb.getName(); | 59 | String name=cb.getName(); | |
| 69 | ; | 60 | ; | |
| 70 | CompoundLockState stateForMethod=getStateForMethod(name); | 61 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 71 | if (stateForMethod != null) { | 62 | if (stateForMethod != null) { | |
| 72 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 73 | } | 64 | } | |
| 74 | } | 65 | } | |
| 75 | } | 66 | } | |
| 76 | } | 67 | } | |
| 77 | return null; | 68 | return null; | |
| 78 | } | 69 | } | |
| 79 | } | 70 | } | |
| 80 | public AnalysisResults(){ | 71 | public AnalysisResults(){ | |
| 81 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 82 | } | 73 | } | |
| 83 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |||
| 76 | public static class Result { | |||
| 77 | private ResultType resultType; | |||
| 78 | private String message; | |||
| 79 | public ResultType getResultType(){ | |||
| 80 | return resultType; | |||
| 81 | } | |||
| 82 | public String getMessage(){ | |||
| 83 | return message; | |||
| 84 | } | |||
| 85 | public Result( ResultType rt, String msg){ | |||
| 86 | message=msg; | |||
| 87 | resultType=rt; | |||
| 88 | } | |||
| 89 | public String toString(){ | |||
| 90 | return (resultType.name() + " " + message); | |||
| 91 | } | |||
| 92 | } | |||
| 84 | /** | 93 | /** | |
| 85 | * Invoke this after the component has been analyzed | 94 | * Invoke this after the component has been analyzed | |
| 86 | * @param component | 95 | * @param component | |
| 87 | */ | 96 | */ | |
| 88 | public void createComponentSummary( Component component){ | 97 | public void createComponentSummary( Component component){ | |
| 89 | ComponentSummary componentSummary=new ComponentSummary(component); | 98 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 90 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 91 | CGNode next=it.next(); | 100 | CGNode next=it.next(); | |
| 92 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 93 | if (exitState != null) { | 102 | if (exitState != null) { | |
| 94 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 95 | componentSummary.registerNodeState(next,compoundLockState); | 104 | componentSummary.registerNodeState(next,compoundLockState); | |
| 96 | } | 105 | } | |
| 97 | } | 106 | } | |
| 98 | allStates.add(Pair.make(component,componentSummary)); | 107 | allStates.add(Pair.make(component,componentSummary)); | |
| 99 | } | 108 | } | |
| 100 | private LockUsage getLockUsage( SingleLockState runState){ | 109 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 101 | if (runState != null) { | 110 | if (runState != null) { | |
| 102 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 103 | return LockUsage.LOCKING; | 112 | return LockUsage.LOCKING; | |
| 104 | } | 113 | } | |
| 105 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 106 | return LockUsage.EMPTY; | 115 | return LockUsage.EMPTY; | |
| 107 | } | 116 | } | |
| 108 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 109 | return LockUsage.FULL_UNLOCKING; | 118 | return LockUsage.FULL_UNLOCKING; | |
| 110 | } | 119 | } | |
| 111 | else if (runState.isMaybeReleased()) { | 120 | else if (runState.isMaybeReleased()) { | |
| 112 | return LockUsage.UNLOCKING; | 121 | return LockUsage.UNLOCKING; | |
| 113 | } | 122 | } | |
| 114 | else { | 123 | else { | |
| 115 | return LockUsage.UNKNOWN_STATE; | 124 | return LockUsage.UNKNOWN_STATE; | |
| 116 | } | 125 | } | |
| 117 | } | 126 | } | |
| 118 | else { | 127 | else { | |
| 119 | return LockUsage.EMPTY; | 128 | return LockUsage.EMPTY; | |
| 120 | } | 129 | } | |
| 121 | } | 130 | } | |
| 122 | public ArrayList<String> processResults(){ | 131 | public ArrayList<Result> processResults(){ | |
| 123 | ArrayList<String> result=null; | 132 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 124 | System.out.println("\n=========================================="); | 133 | System.out.println("\n=========================================="); | |
| 125 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 126 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 127 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 128 | Component component=pair.fst; | 137 | Component component=pair.fst; | |
| 129 | ComponentSummary cSummary=pair.snd; | 138 | ComponentSummary cSummary=pair.snd; | |
| 130 | ComponentPolicy policy=new ComponentPolicy(component); | 139 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 131 | StringBuffer sb=new StringBuffer(); | 140 | StringBuffer sb=new StringBuffer(); | |
| 132 | boolean printComponent=false; | 141 | boolean printComponent=false; | |
| 133 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 134 | CGNode node=e.getKey(); | 143 | CGNode node=e.getKey(); | |
| 135 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 136 | boolean printMethod=false; | 145 | boolean printMethod=false; | |
| 137 | LockUsage lockUsage=LockUsage.EMPTY; | 146 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 138 | CompoundLockState compLS=e.getValue(); | 147 | CompoundLockState compLS=e.getValue(); | |
| 139 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 140 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 141 | WakeLockInstance wli=fs.getKey(); | 150 | WakeLockInstance wli=fs.getKey(); | |
| 142 | Set<SingleLockState> sls=fs.getValue(); | 151 | Set<SingleLockState> sls=fs.getValue(); | |
| 143 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 144 | lockUsage=getLockUsage(sl); | 153 | lockUsage=getLockUsage(sl); | |
| 145 | lockUsages.put(wli,lockUsage); | 154 | lockUsages.put(wli,lockUsage); | |
| 146 | if (lockUsage != LockUsage.EMPTY) { | 155 | if (lockUsage != LockUsage.EMPTY) { | |
| 147 | printMethod=true; | 156 | printMethod=true; | |
| 148 | } | 157 | } | |
| 149 | } | 158 | } | |
| 150 | if (printMethod) { | 159 | if (printMethod) { | |
| 151 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 152 | printComponent=true; | 161 | printComponent=true; | |
| 153 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 154 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 155 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 156 | WakeLockInstance key=fs.getKey(); | 165 | WakeLockInstance key=fs.getKey(); | |
| 157 | Set<SingleLockState> value=fs.getValue(); | 166 | Set<SingleLockState> value=fs.getValue(); | |
| 158 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 159 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 160 | } | 169 | } | |
| 161 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 162 | LockUsage lu=getLockUsage(mergedLS); | 171 | LockUsage lu=getLockUsage(mergedLS); | |
| 163 | if (component.isCallBack(node)) { | 172 | if (component.isCallBack(node)) { | |
| 164 | if (usageMap.containsKey(lu)) { | 173 | if (usageMap.containsKey(lu)) { | |
| 165 | usageMap.get(lu).add(Pair.make(component,node)); | 174 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 166 | } | 175 | } | |
| 167 | else { | 176 | else { | |
| 168 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 169 | set.add(Pair.make(component,node)); | 178 | set.add(Pair.make(component,node)); | |
| 170 | usageMap.put(lu,set); | 179 | usageMap.put(lu,set); | |
| 171 | } | 180 | } | |
| 172 | policy.addFact(node,mergedLS); | 181 | policy.addFact(node,mergedLS); | |
| 173 | } | 182 | } | |
| 174 | } | 183 | } | |
| 175 | } | 184 | } | |
| 176 | } | 185 | } | |
| 177 | if (printComponent) { | 186 | if (printComponent) { | |
| 178 | System.out.println(component.toString() + "\n" + sb.toString()); | 187 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 179 | policy.solveFacts(); | 188 | policy.solveFacts(); | |
| 180 | componentMap.put(component,policy.getLogger()); | 189 | componentMap.put(component,policy.getLogger()); | |
| 181 | } | 190 | } | |
| 182 | } | 191 | } | |
| 183 | System.out.println("==========================================\n"); | 192 | System.out.println("==========================================\n"); | |
| 184 | for ( LockUsage e : usageMap.keySet()) { | 193 | for ( LockUsage e : usageMap.keySet()) { | |
| 185 | System.out.println(e.toString()); | 194 | System.out.println(e.toString()); | |
| 186 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 187 | System.out.println(" " + s.toString()); | 196 | System.out.println(" " + s.toString()); | |
| 188 | } | 197 | } | |
| 189 | } | 198 | } | |
| 190 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 191 | for ( Component e : componentMap.keySet()) { | 200 | for ( Component e : componentMap.keySet()) { | |
| 192 | Logger logger=componentMap.get(e); | 201 | Logger logger=componentMap.get(e); | |
| 193 | if (!logger.isEmpty()) { | 202 | if (!logger.isEmpty()) { | |
| 194 | System.out.println(e.toString()); | 203 | System.out.println(e.toString()); | |
| 195 | System.out.println(logger.toString()); | 204 | System.out.println(logger.toString()); | |
| 196 | System.out.println("\n"); | 205 | System.out.println("\n"); | |
| 197 | } | 206 | } | |
| 198 | result=logger.getStringList(); | 207 | result=logger.getStringList(); | |
| 199 | } | 208 | } | |
| 200 | return result; | 209 | return result; | |
| 201 | } | 210 | } | |
| 202 | public class Logger extends ArrayList<String> { | 211 | public class Logger extends ArrayList<Result> { | |
| 203 | private static final long serialVersionUID=4402714524487791090L; | 212 | private static final long serialVersionUID=4402714524487791090L; | |
| 204 | public void output(){ | 213 | public void output(){ | |
| 205 | for ( String s : this) { | 214 | for ( Result r : this) { | |
| 206 | System.out.println(" " + s); | 215 | System.out.println(" " + r.getResultType().toString()); | |
| 207 | } | 216 | } | |
| 208 | } | 217 | } | |
| 209 | public ArrayList<String> getStringList(){ | 218 | public ArrayList<Result> getStringList(){ | |
| 210 | return this; | 219 | return this; | |
| 211 | } | 220 | } | |
| 212 | public String toString(){ | 221 | public String toString(){ | |
| 213 | StringBuffer result=new StringBuffer(); | 222 | StringBuffer result=new StringBuffer(); | |
| 214 | for ( String s : this) { | 223 | for ( Result r : this) { | |
| 215 | result.append(s + "\n"); | 224 | result.append(r.toString() + "\n"); | |
| 216 | } | 225 | } | |
| 217 | return result.toString(); | 226 | return result.toString(); | |
| 218 | } | 227 | } | |
| 219 | } | 228 | } | |
| 220 | public class ComponentPolicy { | 229 | public class ComponentPolicy { | |
| 221 | private Component component; | 230 | private Component component; | |
| 222 | public ComponentPolicy( Component component){ | 231 | public ComponentPolicy( Component component){ | |
| 223 | this.component=component; | 232 | this.component=component; | |
| 224 | map=new HashMap<String,SingleLockState>(); | 233 | map=new HashMap<String,SingleLockState>(); | |
| 225 | logger=new Logger(); | 234 | logger=new Logger(); | |
| 226 | } | 235 | } | |
| 227 | private HashMap<String,SingleLockState> map; | 236 | private HashMap<String,SingleLockState> map; | |
| 228 | public void addFact( CGNode n, SingleLockState st){ | 237 | public void addFact( CGNode n, SingleLockState st){ | |
| 229 | map.put(n.getMethod().getName().toString(),st); | 238 | map.put(n.getMethod().getName().toString(),st); | |
| 230 | } | 239 | } | |
| 231 | private boolean unlocking( SingleLockState state){ | 240 | private boolean unlocking( SingleLockState state){ | |
| 232 | return (strongUnlocking(state) || weakUnlocking(state)); | 241 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 233 | } | 242 | } | |
| 234 | private boolean strongUnlocking( SingleLockState state){ | 243 | private boolean strongUnlocking( SingleLockState state){ | |
| 235 | if (state != null) { | 244 | if (state != null) { | |
| 236 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 237 | } | 246 | } | |
| 238 | return true; | 247 | return true; | |
| 239 | } | 248 | } | |
| 240 | private boolean weakUnlocking( SingleLockState state){ | 249 | private boolean weakUnlocking( SingleLockState state){ | |
| 241 | if (state != null) { | 250 | if (state != null) { | |
| 242 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 243 | } | 252 | } | |
| 244 | return true; | 253 | return true; | |
| 245 | } | 254 | } | |
| 246 | private boolean locking( SingleLockState onCreateState){ | 255 | private boolean locking( SingleLockState onCreateState){ | |
| 247 | if (onCreateState != null) { | 256 | if (onCreateState != null) { | |
| 248 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 249 | } | 258 | } | |
| 250 | return false; | 259 | return false; | |
| 251 | } | 260 | } | |
| 252 | private Logger logger; | 261 | private Logger logger; | |
| 253 | private void logNote( String s){ | 262 | private void logNote( Result result){ | |
| 254 | logger.add(s); | 263 | logger.add(result); | |
| 255 | } | 264 | } | |
| 256 | public Logger getLogger(){ | 265 | public Logger getLogger(){ | |
| 257 | return logger; | 266 | return logger; | |
| 258 | } | 267 | } | |
| 259 | private SingleLockState getServiceOnStart(){ | 268 | private SingleLockState getServiceOnStart(){ | |
| 260 | SingleLockState onStart=map.get("onStart"); | 269 | SingleLockState onStart=map.get("onStart"); | |
| 261 | SingleLockState onStartCommand=map.get("onStartCommand"); | 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 262 | if (onStartCommand == null) { | 271 | if (onStartCommand == null) { | |
| 263 | return onStart; | 272 | return onStart; | |
| 264 | } | 273 | } | |
| 265 | else { | 274 | else { | |
| 266 | return onStartCommand; | 275 | return onStartCommand; | |
| 267 | } | 276 | } | |
| 268 | } | 277 | } | |
| 269 | /** | 278 | /** | |
| 270 | * TODO: make sure the same lock is locked and unlocked... | 279 | * TODO: make sure the same lock is locked and unlocked... | |
| 271 | */ | 280 | */ | |
| 272 | public void solveFacts(){ | 281 | public void solveFacts(){ | |
| 273 | if (component.getComponentType().equals("Activity")) { | 282 | if (component.getComponentType().equals("Activity")) { | |
| 274 | SingleLockState onCreateState=map.get("onCreate"); | 283 | SingleLockState onCreateState=map.get("onCreate"); | |
| 275 | if (locking(onCreateState)) { | 284 | if (locking(onCreateState)) { | |
| 276 | logNote("STRONG BUG: Locking @ onCreate (" + component.toString() + ")"); | 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 277 | } | 286 | } | |
| 278 | SingleLockState onStartState=map.get("onStart"); | 287 | SingleLockState onStartState=map.get("onStart"); | |
| 279 | if (locking(onStartState)) { | 288 | if (locking(onStartState)) { | |
| 280 | logNote("STRONG BUG: Locking @ onStart (" + component.toString() + ")"); | 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 281 | } | 290 | } | |
| 282 | SingleLockState onRestartState=map.get("onRestart"); | 291 | SingleLockState onRestartState=map.get("onRestart"); | |
| 283 | if (locking(onRestartState)) { | 292 | if (locking(onRestartState)) { | |
| 284 | logNote("STRONG BUG: Locking @ onRestart (" + component.toString() + ")"); | 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 285 | } | 294 | } | |
| 286 | SingleLockState onPauseState=map.get("onPause"); | 295 | SingleLockState onPauseState=map.get("onPause"); | |
| 287 | SingleLockState onResumeState=map.get("onResume"); | |||
| 288 | if (!unlocking(onPauseState)) { | 296 | if (!unlocking(onPauseState)) { | |
| 289 | logNote("STRONG BUG: onPause (" + component.toString() + ")"); | 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 290 | } | 298 | } | |
| 291 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 292 | logNote("WEAK BUG: onPause (" + component.toString() + ")"); | 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 293 | } | 301 | } | |
| 294 | } | 302 | } | |
| 295 | if (component.getComponentType().equals("Service")) { | 303 | if (component.getComponentType().equals("Service")) { | |
| 296 | SingleLockState onStartState=getServiceOnStart(); | 304 | SingleLockState onStartState=getServiceOnStart(); | |
| 297 | SingleLockState onDestroyState=map.get("onDestroy"); | 305 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 298 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 299 | logNote("STRONG BUG: " + component.toString() + "Locking @ onDestroy"); | 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 300 | } | 308 | } | |
| 301 | if (weakUnlocking(onDestroyState)) { | 309 | if (weakUnlocking(onDestroyState)) { | |
| 302 | logNote("WEAK BUG: " + component.toString() + "Weak UnLocking @ onDestroy"); | 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 303 | } | 311 | } | |
| 304 | } | 312 | } | |
| 305 | if (component.getComponentType().equals("RunnableThread")) { | 313 | if (component.getComponentType().equals("RunnableThread")) { | |
| 306 | SingleLockState runState=map.get("run"); | 314 | SingleLockState runState=map.get("run"); | |
| 307 | if (locking(runState)) { | 315 | if (locking(runState)) { | |
| 308 | logNote("WEAK BUG: " + component.toString() + "Locking @ run"); | 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 309 | } | 317 | } | |
| 310 | } | 318 | } | |
| 311 | if (component.getComponentType().equals("Handler")) { | 319 | if (component.getComponentType().equals("Handler")) { | |
| 312 | SingleLockState handleState=map.get("handleMessage"); | 320 | SingleLockState handleState=map.get("handleMessage"); | |
| 313 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 314 | logNote("WEAK BUG: " + component.toString() + "Not full unlocking @ handleMessage"); | 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 315 | } | 323 | } | |
| 316 | } | 324 | } | |
| 317 | if (component.getComponentType().equals("BroadcastReceiver")) { | 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 318 | SingleLockState onReceiveState=map.get("onReceive"); | 326 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 319 | if (locking(onReceiveState)) { | 327 | if (locking(onReceiveState)) { | |
| 320 | logNote("WEAK BUG: " + component.toString() + "Locking @ onReceive"); | 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 321 | } | 329 | } | |
| 322 | } | 330 | } | |
| 323 | } | 331 | } | |
| 324 | } | 332 | } | |
| 325 | } | 333 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_068 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_069 | |||
|---|---|---|---|---|
|
333 lines 13323 bytes Last modified : Mon May 14 23:48:11 2012 |
340 lines 13643 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 18:50:13.586 | 1 | //Time : 2012-04-26 20:48:57.245 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | package energy.analysis; | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |||
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |||
| 6 | CHANGE ReturnStmt to ReturnStmt = 1 | |||
| 7 | changes = 3 | |||
| 8 | changes to method weakUnlocking = 1 | |||
| 9 | private/protected method declarations = 1 | |||
| 10 | */package energy.analysis; | |||
| 4 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 5 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 6 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 7 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 8 | import java.util.Map; | 15 | import java.util.Map; | |
| 9 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 10 | import java.util.Set; | 17 | import java.util.Set; | |
| 11 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 12 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 13 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 14 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 15 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 16 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 17 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 18 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 19 | /** | 26 | /** | |
| 20 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 21 | */ | 28 | */ | |
| 22 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 23 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 24 | private Component component; | 31 | private Component component; | |
| 25 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 26 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 27 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 28 | this.component=c; | 35 | this.component=c; | |
| 29 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 30 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 31 | } | 38 | } | |
| 32 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 33 | return allExitStates; | 40 | return allExitStates; | |
| 34 | } | 41 | } | |
| 35 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 36 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 37 | } | 44 | } | |
| 38 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 39 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 40 | } | 47 | } | |
| 41 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 42 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 43 | } | 50 | } | |
| 44 | public String toString(){ | 51 | public String toString(){ | |
| 45 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 46 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 47 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 48 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 49 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 50 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 51 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 52 | } | 59 | } | |
| 53 | } | 60 | } | |
| 54 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 55 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 56 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 57 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 58 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 59 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 60 | ; | 67 | ; | |
| 61 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 62 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 63 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 64 | } | 71 | } | |
| 65 | } | 72 | } | |
| 66 | } | 73 | } | |
| 67 | } | 74 | } | |
| 68 | return null; | 75 | return null; | |
| 69 | } | 76 | } | |
| 70 | } | 77 | } | |
| 71 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 72 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 73 | } | 80 | } | |
| 74 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 75 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 76 | public static class Result { | 83 | public static class Result { | |
| 77 | private ResultType resultType; | 84 | private ResultType resultType; | |
| 78 | private String message; | 85 | private String message; | |
| 79 | public ResultType getResultType(){ | 86 | public ResultType getResultType(){ | |
| 80 | return resultType; | 87 | return resultType; | |
| 81 | } | 88 | } | |
| 82 | public String getMessage(){ | 89 | public String getMessage(){ | |
| 83 | return message; | 90 | return message; | |
| 84 | } | 91 | } | |
| 85 | public Result( ResultType rt, String msg){ | 92 | public Result( ResultType rt, String msg){ | |
| 86 | message=msg; | 93 | message=msg; | |
| 87 | resultType=rt; | 94 | resultType=rt; | |
| 88 | } | 95 | } | |
| 89 | public String toString(){ | 96 | public String toString(){ | |
| 90 | return (resultType.name() + " " + message); | 97 | return (resultType.name() + " " + message); | |
| 91 | } | 98 | } | |
| 92 | } | 99 | } | |
| 93 | /** | 100 | /** | |
| 94 | * Invoke this after the component has been analyzed | 101 | * Invoke this after the component has been analyzed | |
| 95 | * @param component | 102 | * @param component | |
| 96 | */ | 103 | */ | |
| 97 | public void createComponentSummary( Component component){ | 104 | public void createComponentSummary( Component component){ | |
| 98 | ComponentSummary componentSummary=new ComponentSummary(component); | 105 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 99 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 100 | CGNode next=it.next(); | 107 | CGNode next=it.next(); | |
| 101 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 102 | if (exitState != null) { | 109 | if (exitState != null) { | |
| 103 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 104 | componentSummary.registerNodeState(next,compoundLockState); | 111 | componentSummary.registerNodeState(next,compoundLockState); | |
| 105 | } | 112 | } | |
| 106 | } | 113 | } | |
| 107 | allStates.add(Pair.make(component,componentSummary)); | 114 | allStates.add(Pair.make(component,componentSummary)); | |
| 108 | } | 115 | } | |
| 109 | private LockUsage getLockUsage( SingleLockState runState){ | 116 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 110 | if (runState != null) { | 117 | if (runState != null) { | |
| 111 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 112 | return LockUsage.LOCKING; | 119 | return LockUsage.LOCKING; | |
| 113 | } | 120 | } | |
| 114 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 115 | return LockUsage.EMPTY; | 122 | return LockUsage.EMPTY; | |
| 116 | } | 123 | } | |
| 117 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 118 | return LockUsage.FULL_UNLOCKING; | 125 | return LockUsage.FULL_UNLOCKING; | |
| 119 | } | 126 | } | |
| 120 | else if (runState.isMaybeReleased()) { | 127 | else if (runState.isMaybeReleased()) { | |
| 121 | return LockUsage.UNLOCKING; | 128 | return LockUsage.UNLOCKING; | |
| 122 | } | 129 | } | |
| 123 | else { | 130 | else { | |
| 124 | return LockUsage.UNKNOWN_STATE; | 131 | return LockUsage.UNKNOWN_STATE; | |
| 125 | } | 132 | } | |
| 126 | } | 133 | } | |
| 127 | else { | 134 | else { | |
| 128 | return LockUsage.EMPTY; | 135 | return LockUsage.EMPTY; | |
| 129 | } | 136 | } | |
| 130 | } | 137 | } | |
| 131 | public ArrayList<Result> processResults(){ | 138 | public ArrayList<Result> processResults(){ | |
| 132 | ArrayList<Result> result=new ArrayList<Result>(); | 139 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 133 | System.out.println("\n=========================================="); | 140 | System.out.println("\n=========================================="); | |
| 134 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 135 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 136 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 137 | Component component=pair.fst; | 144 | Component component=pair.fst; | |
| 138 | ComponentSummary cSummary=pair.snd; | 145 | ComponentSummary cSummary=pair.snd; | |
| 139 | ComponentPolicy policy=new ComponentPolicy(component); | 146 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 140 | StringBuffer sb=new StringBuffer(); | 147 | StringBuffer sb=new StringBuffer(); | |
| 141 | boolean printComponent=false; | 148 | boolean printComponent=false; | |
| 142 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 143 | CGNode node=e.getKey(); | 150 | CGNode node=e.getKey(); | |
| 144 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 145 | boolean printMethod=false; | 152 | boolean printMethod=false; | |
| 146 | LockUsage lockUsage=LockUsage.EMPTY; | 153 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 147 | CompoundLockState compLS=e.getValue(); | 154 | CompoundLockState compLS=e.getValue(); | |
| 148 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 149 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 150 | WakeLockInstance wli=fs.getKey(); | 157 | WakeLockInstance wli=fs.getKey(); | |
| 151 | Set<SingleLockState> sls=fs.getValue(); | 158 | Set<SingleLockState> sls=fs.getValue(); | |
| 152 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 153 | lockUsage=getLockUsage(sl); | 160 | lockUsage=getLockUsage(sl); | |
| 154 | lockUsages.put(wli,lockUsage); | 161 | lockUsages.put(wli,lockUsage); | |
| 155 | if (lockUsage != LockUsage.EMPTY) { | 162 | if (lockUsage != LockUsage.EMPTY) { | |
| 156 | printMethod=true; | 163 | printMethod=true; | |
| 157 | } | 164 | } | |
| 158 | } | 165 | } | |
| 159 | if (printMethod) { | 166 | if (printMethod) { | |
| 160 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 161 | printComponent=true; | 168 | printComponent=true; | |
| 162 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 163 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 164 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 165 | WakeLockInstance key=fs.getKey(); | 172 | WakeLockInstance key=fs.getKey(); | |
| 166 | Set<SingleLockState> value=fs.getValue(); | 173 | Set<SingleLockState> value=fs.getValue(); | |
| 167 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 168 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 169 | } | 176 | } | |
| 170 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 171 | LockUsage lu=getLockUsage(mergedLS); | 178 | LockUsage lu=getLockUsage(mergedLS); | |
| 172 | if (component.isCallBack(node)) { | 179 | if (component.isCallBack(node)) { | |
| 173 | if (usageMap.containsKey(lu)) { | 180 | if (usageMap.containsKey(lu)) { | |
| 174 | usageMap.get(lu).add(Pair.make(component,node)); | 181 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 175 | } | 182 | } | |
| 176 | else { | 183 | else { | |
| 177 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 178 | set.add(Pair.make(component,node)); | 185 | set.add(Pair.make(component,node)); | |
| 179 | usageMap.put(lu,set); | 186 | usageMap.put(lu,set); | |
| 180 | } | 187 | } | |
| 181 | policy.addFact(node,mergedLS); | 188 | policy.addFact(node,mergedLS); | |
| 182 | } | 189 | } | |
| 183 | } | 190 | } | |
| 184 | } | 191 | } | |
| 185 | } | 192 | } | |
| 186 | if (printComponent) { | 193 | if (printComponent) { | |
| 187 | System.out.println(component.toString() + "\n" + sb.toString()); | 194 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 188 | policy.solveFacts(); | 195 | policy.solveFacts(); | |
| 189 | componentMap.put(component,policy.getLogger()); | 196 | componentMap.put(component,policy.getLogger()); | |
| 190 | } | 197 | } | |
| 191 | } | 198 | } | |
| 192 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 193 | for ( LockUsage e : usageMap.keySet()) { | 200 | for ( LockUsage e : usageMap.keySet()) { | |
| 194 | System.out.println(e.toString()); | 201 | System.out.println(e.toString()); | |
| 195 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 196 | System.out.println(" " + s.toString()); | 203 | System.out.println(" " + s.toString()); | |
| 197 | } | 204 | } | |
| 198 | } | 205 | } | |
| 199 | System.out.println("==========================================\n"); | 206 | System.out.println("==========================================\n"); | |
| 200 | for ( Component e : componentMap.keySet()) { | 207 | for ( Component e : componentMap.keySet()) { | |
| 201 | Logger logger=componentMap.get(e); | 208 | Logger logger=componentMap.get(e); | |
| 202 | if (!logger.isEmpty()) { | 209 | if (!logger.isEmpty()) { | |
| 203 | System.out.println(e.toString()); | 210 | System.out.println(e.toString()); | |
| 204 | System.out.println(logger.toString()); | 211 | System.out.println(logger.toString()); | |
| 205 | System.out.println("\n"); | 212 | System.out.println("\n"); | |
| 206 | } | 213 | } | |
| 207 | result=logger.getStringList(); | 214 | result=logger.getStringList(); | |
| 208 | } | 215 | } | |
| 209 | return result; | 216 | return result; | |
| 210 | } | 217 | } | |
| 211 | public class Logger extends ArrayList<Result> { | 218 | public class Logger extends ArrayList<Result> { | |
| 212 | private static final long serialVersionUID=4402714524487791090L; | 219 | private static final long serialVersionUID=4402714524487791090L; | |
| 213 | public void output(){ | 220 | public void output(){ | |
| 214 | for ( Result r : this) { | 221 | for ( Result r : this) { | |
| 215 | System.out.println(" " + r.getResultType().toString()); | 222 | System.out.println(" " + r.getResultType().toString()); | |
| 216 | } | 223 | } | |
| 217 | } | 224 | } | |
| 218 | public ArrayList<Result> getStringList(){ | 225 | public ArrayList<Result> getStringList(){ | |
| 219 | return this; | 226 | return this; | |
| 220 | } | 227 | } | |
| 221 | public String toString(){ | 228 | public String toString(){ | |
| 222 | StringBuffer result=new StringBuffer(); | 229 | StringBuffer result=new StringBuffer(); | |
| 223 | for ( Result r : this) { | 230 | for ( Result r : this) { | |
| 224 | result.append(r.toString() + "\n"); | 231 | result.append(r.toString() + "\n"); | |
| 225 | } | 232 | } | |
| 226 | return result.toString(); | 233 | return result.toString(); | |
| 227 | } | 234 | } | |
| 228 | } | 235 | } | |
| 229 | public class ComponentPolicy { | 236 | public class ComponentPolicy { | |
| 230 | private Component component; | 237 | private Component component; | |
| 231 | public ComponentPolicy( Component component){ | 238 | public ComponentPolicy( Component component){ | |
| 232 | this.component=component; | 239 | this.component=component; | |
| 233 | map=new HashMap<String,SingleLockState>(); | 240 | map=new HashMap<String,SingleLockState>(); | |
| 234 | logger=new Logger(); | 241 | logger=new Logger(); | |
| 235 | } | 242 | } | |
| 236 | private HashMap<String,SingleLockState> map; | 243 | private HashMap<String,SingleLockState> map; | |
| 237 | public void addFact( CGNode n, SingleLockState st){ | 244 | public void addFact( CGNode n, SingleLockState st){ | |
| 238 | map.put(n.getMethod().getName().toString(),st); | 245 | map.put(n.getMethod().getName().toString(),st); | |
| 239 | } | 246 | } | |
| 240 | private boolean unlocking( SingleLockState state){ | 247 | private boolean unlocking( SingleLockState state){ | |
| 241 | return (strongUnlocking(state) || weakUnlocking(state)); | 248 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 242 | } | 249 | } | |
| 243 | private boolean strongUnlocking( SingleLockState state){ | 250 | private boolean strongUnlocking( SingleLockState state){ | |
| 244 | if (state != null) { | 251 | if (state != null) { | |
| 245 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 246 | } | 253 | } | |
| 247 | return true; | 254 | return true; | |
| 248 | } | 255 | } | |
| 249 | private boolean weakUnlocking( SingleLockState state){ | 256 | private boolean weakUnlocking( SingleLockState state){ | |
| 250 | if (state != null) { | 257 | if (state != null) { | |
| 251 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 252 | } | 259 | } | |
| 253 | return true; | 260 | return false; | |
| 254 | } | 261 | } | |
| 255 | private boolean locking( SingleLockState onCreateState){ | 262 | private boolean locking( SingleLockState onCreateState){ | |
| 256 | if (onCreateState != null) { | 263 | if (onCreateState != null) { | |
| 257 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 258 | } | 265 | } | |
| 259 | return false; | 266 | return false; | |
| 260 | } | 267 | } | |
| 261 | private Logger logger; | 268 | private Logger logger; | |
| 262 | private void logNote( Result result){ | 269 | private void logNote( Result result){ | |
| 263 | logger.add(result); | 270 | logger.add(result); | |
| 264 | } | 271 | } | |
| 265 | public Logger getLogger(){ | 272 | public Logger getLogger(){ | |
| 266 | return logger; | 273 | return logger; | |
| 267 | } | 274 | } | |
| 268 | private SingleLockState getServiceOnStart(){ | 275 | private SingleLockState getServiceOnStart(){ | |
| 269 | SingleLockState onStart=map.get("onStart"); | 276 | SingleLockState onStart=map.get("onStart"); | |
| 270 | SingleLockState onStartCommand=map.get("onStartCommand"); | 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 271 | if (onStartCommand == null) { | 278 | if (onStartCommand == null) { | |
| 272 | return onStart; | 279 | return onStart; | |
| 273 | } | 280 | } | |
| 274 | else { | 281 | else { | |
| 275 | return onStartCommand; | 282 | return onStartCommand; | |
| 276 | } | 283 | } | |
| 277 | } | 284 | } | |
| 278 | /** | 285 | /** | |
| 279 | * TODO: make sure the same lock is locked and unlocked... | 286 | * TODO: make sure the same lock is locked and unlocked... | |
| 280 | */ | 287 | */ | |
| 281 | public void solveFacts(){ | 288 | public void solveFacts(){ | |
| 282 | if (component.getComponentType().equals("Activity")) { | 289 | if (component.getComponentType().equals("Activity")) { | |
| 283 | SingleLockState onCreateState=map.get("onCreate"); | 290 | SingleLockState onCreateState=map.get("onCreate"); | |
| 284 | if (locking(onCreateState)) { | 291 | if (locking(onCreateState)) { | |
| 285 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 286 | } | 293 | } | |
| 287 | SingleLockState onStartState=map.get("onStart"); | 294 | SingleLockState onStartState=map.get("onStart"); | |
| 288 | if (locking(onStartState)) { | 295 | if (locking(onStartState)) { | |
| 289 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 290 | } | 297 | } | |
| 291 | SingleLockState onRestartState=map.get("onRestart"); | 298 | SingleLockState onRestartState=map.get("onRestart"); | |
| 292 | if (locking(onRestartState)) { | 299 | if (locking(onRestartState)) { | |
| 293 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 294 | } | 301 | } | |
| 295 | SingleLockState onPauseState=map.get("onPause"); | 302 | SingleLockState onPauseState=map.get("onPause"); | |
| 296 | if (!unlocking(onPauseState)) { | 303 | if (!unlocking(onPauseState)) { | |
| 297 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 298 | } | 305 | } | |
| 299 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 300 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 301 | } | 308 | } | |
| 302 | } | 309 | } | |
| 303 | if (component.getComponentType().equals("Service")) { | 310 | if (component.getComponentType().equals("Service")) { | |
| 304 | SingleLockState onStartState=getServiceOnStart(); | 311 | SingleLockState onStartState=getServiceOnStart(); | |
| 305 | SingleLockState onDestroyState=map.get("onDestroy"); | 312 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 306 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 307 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 308 | } | 315 | } | |
| 309 | if (weakUnlocking(onDestroyState)) { | 316 | if (weakUnlocking(onDestroyState)) { | |
| 310 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 311 | } | 318 | } | |
| 312 | } | 319 | } | |
| 313 | if (component.getComponentType().equals("RunnableThread")) { | 320 | if (component.getComponentType().equals("RunnableThread")) { | |
| 314 | SingleLockState runState=map.get("run"); | 321 | SingleLockState runState=map.get("run"); | |
| 315 | if (locking(runState)) { | 322 | if (locking(runState)) { | |
| 316 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 317 | } | 324 | } | |
| 318 | } | 325 | } | |
| 319 | if (component.getComponentType().equals("Handler")) { | 326 | if (component.getComponentType().equals("Handler")) { | |
| 320 | SingleLockState handleState=map.get("handleMessage"); | 327 | SingleLockState handleState=map.get("handleMessage"); | |
| 321 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 323 | } | 330 | } | |
| 324 | } | 331 | } | |
| 325 | if (component.getComponentType().equals("BroadcastReceiver")) { | 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 326 | SingleLockState onReceiveState=map.get("onReceive"); | 333 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 327 | if (locking(onReceiveState)) { | 334 | if (locking(onReceiveState)) { | |
| 328 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 329 | } | 336 | } | |
| 330 | } | 337 | } | |
| 331 | } | 338 | } | |
| 332 | } | 339 | } | |
| 333 | } | 340 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_069 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_070 | |||
|---|---|---|---|---|
|
340 lines 13643 bytes Last modified : Mon May 14 23:48:12 2012 |
340 lines 13642 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:48:57.245 | 1 | //Time : 2012-04-26 20:49:20.139 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | CHANGE ReturnStmt to ReturnStmt = 1 | 6 | CHANGE ReturnStmt to ReturnStmt = 1 | |
| 7 | changes = 3 | 7 | changes = 3 | |
| 8 | changes to method weakUnlocking = 1 | 8 | changes to method weakUnlocking = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 26 | /** | 26 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 28 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 31 | private Component component; | 31 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 35 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 38 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 40 | return allExitStates; | |
| 41 | } | 41 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 44 | } | 44 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 47 | } | 47 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 50 | } | 50 | } | |
| 51 | public String toString(){ | 51 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 59 | } | |
| 60 | } | 60 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 67 | ; | 67 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 71 | } | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | return null; | 75 | return null; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 80 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 83 | public static class Result { | 83 | public static class Result { | |
| 84 | private ResultType resultType; | 84 | private ResultType resultType; | |
| 85 | private String message; | 85 | private String message; | |
| 86 | public ResultType getResultType(){ | 86 | public ResultType getResultType(){ | |
| 87 | return resultType; | 87 | return resultType; | |
| 88 | } | 88 | } | |
| 89 | public String getMessage(){ | 89 | public String getMessage(){ | |
| 90 | return message; | 90 | return message; | |
| 91 | } | 91 | } | |
| 92 | public Result( ResultType rt, String msg){ | 92 | public Result( ResultType rt, String msg){ | |
| 93 | message=msg; | 93 | message=msg; | |
| 94 | resultType=rt; | 94 | resultType=rt; | |
| 95 | } | 95 | } | |
| 96 | public String toString(){ | 96 | public String toString(){ | |
| 97 | return (resultType.name() + " " + message); | 97 | return (resultType.name() + " " + message); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | /** | 100 | /** | |
| 101 | * Invoke this after the component has been analyzed | 101 | * Invoke this after the component has been analyzed | |
| 102 | * @param component | 102 | * @param component | |
| 103 | */ | 103 | */ | |
| 104 | public void createComponentSummary( Component component){ | 104 | public void createComponentSummary( Component component){ | |
| 105 | ComponentSummary componentSummary=new ComponentSummary(component); | 105 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 107 | CGNode next=it.next(); | 107 | CGNode next=it.next(); | |
| 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 109 | if (exitState != null) { | 109 | if (exitState != null) { | |
| 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 111 | componentSummary.registerNodeState(next,compoundLockState); | 111 | componentSummary.registerNodeState(next,compoundLockState); | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | allStates.add(Pair.make(component,componentSummary)); | 114 | allStates.add(Pair.make(component,componentSummary)); | |
| 115 | } | 115 | } | |
| 116 | private LockUsage getLockUsage( SingleLockState runState){ | 116 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 117 | if (runState != null) { | 117 | if (runState != null) { | |
| 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 119 | return LockUsage.LOCKING; | 119 | return LockUsage.LOCKING; | |
| 120 | } | 120 | } | |
| 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 122 | return LockUsage.EMPTY; | 122 | return LockUsage.EMPTY; | |
| 123 | } | 123 | } | |
| 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 125 | return LockUsage.FULL_UNLOCKING; | 125 | return LockUsage.FULL_UNLOCKING; | |
| 126 | } | 126 | } | |
| 127 | else if (runState.isMaybeReleased()) { | 127 | else if (runState.isMaybeReleased()) { | |
| 128 | return LockUsage.UNLOCKING; | 128 | return LockUsage.UNLOCKING; | |
| 129 | } | 129 | } | |
| 130 | else { | 130 | else { | |
| 131 | return LockUsage.UNKNOWN_STATE; | 131 | return LockUsage.UNKNOWN_STATE; | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } | |
| 134 | else { | 134 | else { | |
| 135 | return LockUsage.EMPTY; | 135 | return LockUsage.EMPTY; | |
| 136 | } | 136 | } | |
| 137 | } | 137 | } | |
| 138 | public ArrayList<Result> processResults(){ | 138 | public ArrayList<Result> processResults(){ | |
| 139 | ArrayList<Result> result=new ArrayList<Result>(); | 139 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 140 | System.out.println("\n=========================================="); | 140 | System.out.println("\n=========================================="); | |
| 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 144 | Component component=pair.fst; | 144 | Component component=pair.fst; | |
| 145 | ComponentSummary cSummary=pair.snd; | 145 | ComponentSummary cSummary=pair.snd; | |
| 146 | ComponentPolicy policy=new ComponentPolicy(component); | 146 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 147 | StringBuffer sb=new StringBuffer(); | 147 | StringBuffer sb=new StringBuffer(); | |
| 148 | boolean printComponent=false; | 148 | boolean printComponent=false; | |
| 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 150 | CGNode node=e.getKey(); | 150 | CGNode node=e.getKey(); | |
| 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 152 | boolean printMethod=false; | 152 | boolean printMethod=false; | |
| 153 | LockUsage lockUsage=LockUsage.EMPTY; | 153 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 154 | CompoundLockState compLS=e.getValue(); | 154 | CompoundLockState compLS=e.getValue(); | |
| 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 157 | WakeLockInstance wli=fs.getKey(); | 157 | WakeLockInstance wli=fs.getKey(); | |
| 158 | Set<SingleLockState> sls=fs.getValue(); | 158 | Set<SingleLockState> sls=fs.getValue(); | |
| 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 160 | lockUsage=getLockUsage(sl); | 160 | lockUsage=getLockUsage(sl); | |
| 161 | lockUsages.put(wli,lockUsage); | 161 | lockUsages.put(wli,lockUsage); | |
| 162 | if (lockUsage != LockUsage.EMPTY) { | 162 | if (lockUsage != LockUsage.EMPTY) { | |
| 163 | printMethod=true; | 163 | printMethod=true; | |
| 164 | } | 164 | } | |
| 165 | } | 165 | } | |
| 166 | if (printMethod) { | 166 | if (printMethod) { | |
| 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 168 | printComponent=true; | 168 | printComponent=true; | |
| 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 172 | WakeLockInstance key=fs.getKey(); | 172 | WakeLockInstance key=fs.getKey(); | |
| 173 | Set<SingleLockState> value=fs.getValue(); | 173 | Set<SingleLockState> value=fs.getValue(); | |
| 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 176 | } | 176 | } | |
| 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 178 | LockUsage lu=getLockUsage(mergedLS); | 178 | LockUsage lu=getLockUsage(mergedLS); | |
| 179 | if (component.isCallBack(node)) { | 179 | if (component.isCallBack(node)) { | |
| 180 | if (usageMap.containsKey(lu)) { | 180 | if (usageMap.containsKey(lu)) { | |
| 181 | usageMap.get(lu).add(Pair.make(component,node)); | 181 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 182 | } | 182 | } | |
| 183 | else { | 183 | else { | |
| 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 185 | set.add(Pair.make(component,node)); | 185 | set.add(Pair.make(component,node)); | |
| 186 | usageMap.put(lu,set); | 186 | usageMap.put(lu,set); | |
| 187 | } | 187 | } | |
| 188 | policy.addFact(node,mergedLS); | 188 | policy.addFact(node,mergedLS); | |
| 189 | } | 189 | } | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | } | 192 | } | |
| 193 | if (printComponent) { | 193 | if (printComponent) { | |
| 194 | System.out.println(component.toString() + "\n" + sb.toString()); | 194 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 195 | policy.solveFacts(); | 195 | policy.solveFacts(); | |
| 196 | componentMap.put(component,policy.getLogger()); | 196 | componentMap.put(component,policy.getLogger()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( LockUsage e : usageMap.keySet()) { | 200 | for ( LockUsage e : usageMap.keySet()) { | |
| 201 | System.out.println(e.toString()); | 201 | System.out.println(e.toString()); | |
| 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 203 | System.out.println(" " + s.toString()); | 203 | System.out.println(" " + s.toString()); | |
| 204 | } | 204 | } | |
| 205 | } | 205 | } | |
| 206 | System.out.println("==========================================\n"); | 206 | System.out.println("==========================================\n"); | |
| 207 | for ( Component e : componentMap.keySet()) { | 207 | for ( Component e : componentMap.keySet()) { | |
| 208 | Logger logger=componentMap.get(e); | 208 | Logger logger=componentMap.get(e); | |
| 209 | if (!logger.isEmpty()) { | 209 | if (!logger.isEmpty()) { | |
| 210 | System.out.println(e.toString()); | 210 | System.out.println(e.toString()); | |
| 211 | System.out.println(logger.toString()); | 211 | System.out.println(logger.toString()); | |
| 212 | System.out.println("\n"); | 212 | System.out.println("\n"); | |
| 213 | } | 213 | } | |
| 214 | result=logger.getStringList(); | 214 | result=logger.getStringList(); | |
| 215 | } | 215 | } | |
| 216 | return result; | 216 | return result; | |
| 217 | } | 217 | } | |
| 218 | public class Logger extends ArrayList<Result> { | 218 | public class Logger extends ArrayList<Result> { | |
| 219 | private static final long serialVersionUID=4402714524487791090L; | 219 | private static final long serialVersionUID=4402714524487791090L; | |
| 220 | public void output(){ | 220 | public void output(){ | |
| 221 | for ( Result r : this) { | 221 | for ( Result r : this) { | |
| 222 | System.out.println(" " + r.getResultType().toString()); | 222 | System.out.println(" " + r.getResultType().toString()); | |
| 223 | } | 223 | } | |
| 224 | } | 224 | } | |
| 225 | public ArrayList<Result> getStringList(){ | 225 | public ArrayList<Result> getStringList(){ | |
| 226 | return this; | 226 | return this; | |
| 227 | } | 227 | } | |
| 228 | public String toString(){ | 228 | public String toString(){ | |
| 229 | StringBuffer result=new StringBuffer(); | 229 | StringBuffer result=new StringBuffer(); | |
| 230 | for ( Result r : this) { | 230 | for ( Result r : this) { | |
| 231 | result.append(r.toString() + "\n"); | 231 | result.append(r.toString() + "\n"); | |
| 232 | } | 232 | } | |
| 233 | return result.toString(); | 233 | return result.toString(); | |
| 234 | } | 234 | } | |
| 235 | } | 235 | } | |
| 236 | public class ComponentPolicy { | 236 | public class ComponentPolicy { | |
| 237 | private Component component; | 237 | private Component component; | |
| 238 | public ComponentPolicy( Component component){ | 238 | public ComponentPolicy( Component component){ | |
| 239 | this.component=component; | 239 | this.component=component; | |
| 240 | map=new HashMap<String,SingleLockState>(); | 240 | map=new HashMap<String,SingleLockState>(); | |
| 241 | logger=new Logger(); | 241 | logger=new Logger(); | |
| 242 | } | 242 | } | |
| 243 | private HashMap<String,SingleLockState> map; | 243 | private HashMap<String,SingleLockState> map; | |
| 244 | public void addFact( CGNode n, SingleLockState st){ | 244 | public void addFact( CGNode n, SingleLockState st){ | |
| 245 | map.put(n.getMethod().getName().toString(),st); | 245 | map.put(n.getMethod().getName().toString(),st); | |
| 246 | } | 246 | } | |
| 247 | private boolean unlocking( SingleLockState state){ | 247 | private boolean unlocking( SingleLockState state){ | |
| 248 | return (strongUnlocking(state) || weakUnlocking(state)); | 248 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 249 | } | 249 | } | |
| 250 | private boolean strongUnlocking( SingleLockState state){ | 250 | private boolean strongUnlocking( SingleLockState state){ | |
| 251 | if (state != null) { | 251 | if (state != null) { | |
| 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 253 | } | 253 | } | |
| 254 | return true; | 254 | return true; | |
| 255 | } | 255 | } | |
| 256 | private boolean weakUnlocking( SingleLockState state){ | 256 | private boolean weakUnlocking( SingleLockState state){ | |
| 257 | if (state != null) { | 257 | if (state != null) { | |
| 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 259 | } | 259 | } | |
| 260 | return false; | 260 | return true; | |
| 261 | } | 261 | } | |
| 262 | private boolean locking( SingleLockState onCreateState){ | 262 | private boolean locking( SingleLockState onCreateState){ | |
| 263 | if (onCreateState != null) { | 263 | if (onCreateState != null) { | |
| 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 265 | } | 265 | } | |
| 266 | return false; | 266 | return false; | |
| 267 | } | 267 | } | |
| 268 | private Logger logger; | 268 | private Logger logger; | |
| 269 | private void logNote( Result result){ | 269 | private void logNote( Result result){ | |
| 270 | logger.add(result); | 270 | logger.add(result); | |
| 271 | } | 271 | } | |
| 272 | public Logger getLogger(){ | 272 | public Logger getLogger(){ | |
| 273 | return logger; | 273 | return logger; | |
| 274 | } | 274 | } | |
| 275 | private SingleLockState getServiceOnStart(){ | 275 | private SingleLockState getServiceOnStart(){ | |
| 276 | SingleLockState onStart=map.get("onStart"); | 276 | SingleLockState onStart=map.get("onStart"); | |
| 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 278 | if (onStartCommand == null) { | 278 | if (onStartCommand == null) { | |
| 279 | return onStart; | 279 | return onStart; | |
| 280 | } | 280 | } | |
| 281 | else { | 281 | else { | |
| 282 | return onStartCommand; | 282 | return onStartCommand; | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | /** | 285 | /** | |
| 286 | * TODO: make sure the same lock is locked and unlocked... | 286 | * TODO: make sure the same lock is locked and unlocked... | |
| 287 | */ | 287 | */ | |
| 288 | public void solveFacts(){ | 288 | public void solveFacts(){ | |
| 289 | if (component.getComponentType().equals("Activity")) { | 289 | if (component.getComponentType().equals("Activity")) { | |
| 290 | SingleLockState onCreateState=map.get("onCreate"); | 290 | SingleLockState onCreateState=map.get("onCreate"); | |
| 291 | if (locking(onCreateState)) { | 291 | if (locking(onCreateState)) { | |
| 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 293 | } | 293 | } | |
| 294 | SingleLockState onStartState=map.get("onStart"); | 294 | SingleLockState onStartState=map.get("onStart"); | |
| 295 | if (locking(onStartState)) { | 295 | if (locking(onStartState)) { | |
| 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 297 | } | 297 | } | |
| 298 | SingleLockState onRestartState=map.get("onRestart"); | 298 | SingleLockState onRestartState=map.get("onRestart"); | |
| 299 | if (locking(onRestartState)) { | 299 | if (locking(onRestartState)) { | |
| 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | SingleLockState onPauseState=map.get("onPause"); | 302 | SingleLockState onPauseState=map.get("onPause"); | |
| 303 | if (!unlocking(onPauseState)) { | 303 | if (!unlocking(onPauseState)) { | |
| 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 305 | } | 305 | } | |
| 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("Service")) { | 310 | if (component.getComponentType().equals("Service")) { | |
| 311 | SingleLockState onStartState=getServiceOnStart(); | 311 | SingleLockState onStartState=getServiceOnStart(); | |
| 312 | SingleLockState onDestroyState=map.get("onDestroy"); | 312 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 315 | } | 315 | } | |
| 316 | if (weakUnlocking(onDestroyState)) { | 316 | if (weakUnlocking(onDestroyState)) { | |
| 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | if (component.getComponentType().equals("RunnableThread")) { | 320 | if (component.getComponentType().equals("RunnableThread")) { | |
| 321 | SingleLockState runState=map.get("run"); | 321 | SingleLockState runState=map.get("run"); | |
| 322 | if (locking(runState)) { | 322 | if (locking(runState)) { | |
| 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } | |
| 326 | if (component.getComponentType().equals("Handler")) { | 326 | if (component.getComponentType().equals("Handler")) { | |
| 327 | SingleLockState handleState=map.get("handleMessage"); | 327 | SingleLockState handleState=map.get("handleMessage"); | |
| 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 333 | SingleLockState onReceiveState=map.get("onReceive"); | 333 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 334 | if (locking(onReceiveState)) { | 334 | if (locking(onReceiveState)) { | |
| 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 336 | } | 336 | } | |
| 337 | } | 337 | } | |
| 338 | } | 338 | } | |
| 339 | } | 339 | } | |
| 340 | } | 340 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_070 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_071 | |||
|---|---|---|---|---|
|
340 lines 13642 bytes Last modified : Mon May 14 23:48:12 2012 |
317 lines 12643 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:20.139 | 1 | //Time : 2012-04-26 20:49:37.253 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt ExpressionStmt IfStmt to IfStmt IfStmt IfStmt IfStmt = 1 | |||
| 5 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 6 | CHANGE ReturnStmt to ReturnStmt = 1 | |||
| 7 | changes = 3 | 7 | changes = 3 | |
| 8 | changes to method weakUnlocking = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 26 | /** | 26 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 28 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 31 | private Component component; | 31 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 35 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 38 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 40 | return allExitStates; | |
| 41 | } | 41 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 44 | } | 44 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 47 | } | 47 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 50 | } | 50 | } | |
| 51 | public String toString(){ | 51 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 59 | } | |
| 60 | } | 60 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 67 | ; | 67 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 71 | } | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | return null; | 75 | return null; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 80 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 83 | public static class Result { | 83 | public static class Result { | |
| 84 | private ResultType resultType; | 84 | private ResultType resultType; | |
| 85 | private String message; | 85 | private String message; | |
| 86 | public ResultType getResultType(){ | 86 | public ResultType getResultType(){ | |
| 87 | return resultType; | 87 | return resultType; | |
| 88 | } | 88 | } | |
| 89 | public String getMessage(){ | 89 | public String getMessage(){ | |
| 90 | return message; | 90 | return message; | |
| 91 | } | 91 | } | |
| 92 | public Result( ResultType rt, String msg){ | 92 | public Result( ResultType rt, String msg){ | |
| 93 | message=msg; | 93 | message=msg; | |
| 94 | resultType=rt; | 94 | resultType=rt; | |
| 95 | } | 95 | } | |
| 96 | public String toString(){ | 96 | public String toString(){ | |
| 97 | return (resultType.name() + " " + message); | 97 | return (resultType.name() + " " + message); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | /** | 100 | /** | |
| 101 | * Invoke this after the component has been analyzed | 101 | * Invoke this after the component has been analyzed | |
| 102 | * @param component | 102 | * @param component | |
| 103 | */ | 103 | */ | |
| 104 | public void createComponentSummary( Component component){ | 104 | public void createComponentSummary( Component component){ | |
| 105 | ComponentSummary componentSummary=new ComponentSummary(component); | 105 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 107 | CGNode next=it.next(); | 107 | CGNode next=it.next(); | |
| 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 109 | if (exitState != null) { | 109 | if (exitState != null) { | |
| 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 111 | componentSummary.registerNodeState(next,compoundLockState); | 111 | componentSummary.registerNodeState(next,compoundLockState); | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | allStates.add(Pair.make(component,componentSummary)); | 114 | allStates.add(Pair.make(component,componentSummary)); | |
| 115 | } | 115 | } | |
| 116 | private LockUsage getLockUsage( SingleLockState runState){ | 116 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 117 | if (runState != null) { | 117 | if (runState != null) { | |
| 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 119 | return LockUsage.LOCKING; | 119 | return LockUsage.LOCKING; | |
| 120 | } | 120 | } | |
| 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 122 | return LockUsage.EMPTY; | 122 | return LockUsage.EMPTY; | |
| 123 | } | 123 | } | |
| 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 125 | return LockUsage.FULL_UNLOCKING; | 125 | return LockUsage.FULL_UNLOCKING; | |
| 126 | } | 126 | } | |
| 127 | else if (runState.isMaybeReleased()) { | 127 | else if (runState.isMaybeReleased()) { | |
| 128 | return LockUsage.UNLOCKING; | 128 | return LockUsage.UNLOCKING; | |
| 129 | } | 129 | } | |
| 130 | else { | 130 | else { | |
| 131 | return LockUsage.UNKNOWN_STATE; | 131 | return LockUsage.UNKNOWN_STATE; | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } | |
| 134 | else { | 134 | else { | |
| 135 | return LockUsage.EMPTY; | 135 | return LockUsage.EMPTY; | |
| 136 | } | 136 | } | |
| 137 | } | 137 | } | |
| 138 | public ArrayList<Result> processResults(){ | 138 | public ArrayList<Result> processResults(){ | |
| 139 | ArrayList<Result> result=new ArrayList<Result>(); | 139 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 140 | System.out.println("\n=========================================="); | 140 | System.out.println("\n=========================================="); | |
| 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 144 | Component component=pair.fst; | 144 | Component component=pair.fst; | |
| 145 | ComponentSummary cSummary=pair.snd; | 145 | ComponentSummary cSummary=pair.snd; | |
| 146 | ComponentPolicy policy=new ComponentPolicy(component); | 146 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 147 | StringBuffer sb=new StringBuffer(); | 147 | StringBuffer sb=new StringBuffer(); | |
| 148 | boolean printComponent=false; | 148 | boolean printComponent=false; | |
| 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 150 | CGNode node=e.getKey(); | 150 | CGNode node=e.getKey(); | |
| 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 152 | boolean printMethod=false; | 152 | boolean printMethod=false; | |
| 153 | LockUsage lockUsage=LockUsage.EMPTY; | 153 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 154 | CompoundLockState compLS=e.getValue(); | 154 | CompoundLockState compLS=e.getValue(); | |
| 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 157 | WakeLockInstance wli=fs.getKey(); | 157 | WakeLockInstance wli=fs.getKey(); | |
| 158 | Set<SingleLockState> sls=fs.getValue(); | 158 | Set<SingleLockState> sls=fs.getValue(); | |
| 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 160 | lockUsage=getLockUsage(sl); | 160 | lockUsage=getLockUsage(sl); | |
| 161 | lockUsages.put(wli,lockUsage); | 161 | lockUsages.put(wli,lockUsage); | |
| 162 | if (lockUsage != LockUsage.EMPTY) { | 162 | if (lockUsage != LockUsage.EMPTY) { | |
| 163 | printMethod=true; | 163 | printMethod=true; | |
| 164 | } | 164 | } | |
| 165 | } | 165 | } | |
| 166 | if (printMethod) { | 166 | if (printMethod) { | |
| 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 168 | printComponent=true; | 168 | printComponent=true; | |
| 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 172 | WakeLockInstance key=fs.getKey(); | 172 | WakeLockInstance key=fs.getKey(); | |
| 173 | Set<SingleLockState> value=fs.getValue(); | 173 | Set<SingleLockState> value=fs.getValue(); | |
| 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 176 | } | 176 | } | |
| 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 178 | LockUsage lu=getLockUsage(mergedLS); | 178 | LockUsage lu=getLockUsage(mergedLS); | |
| 179 | if (component.isCallBack(node)) { | 179 | if (component.isCallBack(node)) { | |
| 180 | if (usageMap.containsKey(lu)) { | 180 | if (usageMap.containsKey(lu)) { | |
| 181 | usageMap.get(lu).add(Pair.make(component,node)); | 181 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 182 | } | 182 | } | |
| 183 | else { | 183 | else { | |
| 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 185 | set.add(Pair.make(component,node)); | 185 | set.add(Pair.make(component,node)); | |
| 186 | usageMap.put(lu,set); | 186 | usageMap.put(lu,set); | |
| 187 | } | 187 | } | |
| 188 | policy.addFact(node,mergedLS); | 188 | policy.addFact(node,mergedLS); | |
| 189 | } | 189 | } | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | } | 192 | } | |
| 193 | if (printComponent) { | 193 | if (printComponent) { | |
| 194 | System.out.println(component.toString() + "\n" + sb.toString()); | 194 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 195 | policy.solveFacts(); | 195 | policy.solveFacts(); | |
| 196 | componentMap.put(component,policy.getLogger()); | 196 | componentMap.put(component,policy.getLogger()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( LockUsage e : usageMap.keySet()) { | 200 | for ( LockUsage e : usageMap.keySet()) { | |
| 201 | System.out.println(e.toString()); | 201 | System.out.println(e.toString()); | |
| 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 203 | System.out.println(" " + s.toString()); | 203 | System.out.println(" " + s.toString()); | |
| 204 | } | 204 | } | |
| 205 | } | 205 | } | |
| 206 | System.out.println("==========================================\n"); | 206 | System.out.println("==========================================\n"); | |
| 207 | for ( Component e : componentMap.keySet()) { | 207 | for ( Component e : componentMap.keySet()) { | |
| 208 | Logger logger=componentMap.get(e); | 208 | Logger logger=componentMap.get(e); | |
| 209 | if (!logger.isEmpty()) { | 209 | if (!logger.isEmpty()) { | |
| 210 | System.out.println(e.toString()); | 210 | System.out.println(e.toString()); | |
| 211 | System.out.println(logger.toString()); | 211 | System.out.println(logger.toString()); | |
| 212 | System.out.println("\n"); | 212 | System.out.println("\n"); | |
| 213 | } | 213 | } | |
| 214 | result=logger.getStringList(); | 214 | result=logger.getStringList(); | |
| 215 | } | 215 | } | |
| 216 | return result; | 216 | return result; | |
| 217 | } | 217 | } | |
| 218 | public class Logger extends ArrayList<Result> { | 218 | public class Logger extends ArrayList<Result> { | |
| 219 | private static final long serialVersionUID=4402714524487791090L; | 219 | private static final long serialVersionUID=4402714524487791090L; | |
| 220 | public void output(){ | 220 | public void output(){ | |
| 221 | for ( Result r : this) { | 221 | for ( Result r : this) { | |
| 222 | System.out.println(" " + r.getResultType().toString()); | 222 | System.out.println(" " + r.getResultType().toString()); | |
| 223 | } | 223 | } | |
| 224 | } | 224 | } | |
| 225 | public ArrayList<Result> getStringList(){ | 225 | public ArrayList<Result> getStringList(){ | |
| 226 | return this; | 226 | return this; | |
| 227 | } | 227 | } | |
| 228 | public String toString(){ | 228 | public String toString(){ | |
| 229 | StringBuffer result=new StringBuffer(); | 229 | StringBuffer result=new StringBuffer(); | |
| 230 | for ( Result r : this) { | 230 | for ( Result r : this) { | |
| 231 | result.append(r.toString() + "\n"); | 231 | result.append(r.toString() + "\n"); | |
| 232 | } | 232 | } | |
| 233 | return result.toString(); | 233 | return result.toString(); | |
| 234 | } | 234 | } | |
| 235 | } | 235 | } | |
| 236 | public class ComponentPolicy { | 236 | public class ComponentPolicy { | |
| 237 | private Component component; | 237 | private Component component; | |
| 238 | public ComponentPolicy( Component component){ | 238 | public ComponentPolicy( Component component){ | |
| 239 | this.component=component; | 239 | this.component=component; | |
| 240 | map=new HashMap<String,SingleLockState>(); | 240 | map=new HashMap<String,SingleLockState>(); | |
| 241 | logger=new Logger(); | 241 | logger=new Logger(); | |
| 242 | } | 242 | } | |
| 243 | private HashMap<String,SingleLockState> map; | 243 | private HashMap<String,SingleLockState> map; | |
| 244 | public void addFact( CGNode n, SingleLockState st){ | 244 | public void addFact( CGNode n, SingleLockState st){ | |
| 245 | map.put(n.getMethod().getName().toString(),st); | 245 | map.put(n.getMethod().getName().toString(),st); | |
| 246 | } | 246 | } | |
| 247 | private boolean unlocking( SingleLockState state){ | 247 | private boolean unlocking( SingleLockState state){ | |
| 248 | return (strongUnlocking(state) || weakUnlocking(state)); | 248 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 249 | } | 249 | } | |
| 250 | private boolean strongUnlocking( SingleLockState state){ | 250 | private boolean strongUnlocking( SingleLockState state){ | |
| 251 | if (state != null) { | 251 | if (state != null) { | |
| 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 253 | } | 253 | } | |
| 254 | return true; | 254 | return true; | |
| 255 | } | 255 | } | |
| 256 | private boolean weakUnlocking( SingleLockState state){ | 256 | private boolean weakUnlocking( SingleLockState state){ | |
| 257 | if (state != null) { | 257 | if (state != null) { | |
| 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 259 | } | 259 | } | |
| 260 | return true; | 260 | return true; | |
| 261 | } | 261 | } | |
| 262 | private boolean locking( SingleLockState onCreateState){ | 262 | private boolean locking( SingleLockState onCreateState){ | |
| 263 | if (onCreateState != null) { | 263 | if (onCreateState != null) { | |
| 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 265 | } | 265 | } | |
| 266 | return false; | 266 | return false; | |
| 267 | } | 267 | } | |
| 268 | private Logger logger; | 268 | private Logger logger; | |
| 269 | private void logNote( Result result){ | 269 | private void logNote( Result result){ | |
| 270 | logger.add(result); | 270 | logger.add(result); | |
| 271 | } | 271 | } | |
| 272 | public Logger getLogger(){ | 272 | public Logger getLogger(){ | |
| 273 | return logger; | 273 | return logger; | |
| 274 | } | 274 | } | |
| 275 | private SingleLockState getServiceOnStart(){ | 275 | private SingleLockState getServiceOnStart(){ | |
| 276 | SingleLockState onStart=map.get("onStart"); | 276 | SingleLockState onStart=map.get("onStart"); | |
| 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 278 | if (onStartCommand == null) { | 278 | if (onStartCommand == null) { | |
| 279 | return onStart; | 279 | return onStart; | |
| 280 | } | 280 | } | |
| 281 | else { | 281 | else { | |
| 282 | return onStartCommand; | 282 | return onStartCommand; | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | /** | 285 | /** | |
| 286 | * TODO: make sure the same lock is locked and unlocked... | 286 | * TODO: make sure the same lock is locked and unlocked... | |
| 287 | */ | 287 | */ | |
| 288 | public void solveFacts(){ | 288 | public void solveFacts(){ | |
| 289 | if (component.getComponentType().equals("Activity")) { | 289 | if (component.getComponentType().equals("Activity")) { | |
| 290 | SingleLockState onCreateState=map.get("onCreate"); | 290 | SingleLockState onCreateState=map.get("onCreate"); | |
| 291 | if (locking(onCreateState)) { | 291 | if (locking(onCreateState)) { | |
| 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 293 | } | 293 | } | |
| 294 | SingleLockState onStartState=map.get("onStart"); | 294 | SingleLockState onStartState=map.get("onStart"); | |
| 295 | if (locking(onStartState)) { | 295 | if (locking(onStartState)) { | |
| 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 297 | } | 297 | } | |
| 298 | SingleLockState onRestartState=map.get("onRestart"); | 298 | SingleLockState onRestartState=map.get("onRestart"); | |
| 299 | if (locking(onRestartState)) { | 299 | if (locking(onRestartState)) { | |
| 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | SingleLockState onPauseState=map.get("onPause"); | 302 | SingleLockState onPauseState=map.get("onPause"); | |
| 303 | if (!unlocking(onPauseState)) { | 303 | if (!unlocking(onPauseState)) { | |
| 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 305 | } | 305 | } | |
| 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("Service")) { | 310 | SingleLockState onStartState=getServiceOnStart(); | |
| 311 | SingleLockState onStartState=getServiceOnStart(); | 311 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 312 | SingleLockState onDestroyState=map.get("onDestroy"); | 312 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 313 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |||
| 315 | } | |||
| 316 | if (weakUnlocking(onDestroyState)) { | |||
| 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |||
| 318 | } | |||
| 319 | } | |||
| 320 | if (component.getComponentType().equals("RunnableThread")) { | |||
| 321 | SingleLockState runState=map.get("run"); | |||
| 322 | if (locking(runState)) { | |||
| 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |||
| 324 | } | |||
| 325 | } | |||
| 326 | if (component.getComponentType().equals("Handler")) { | |||
| 327 | SingleLockState handleState=map.get("handleMessage"); | |||
| 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |||
| 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |||
| 330 | } | |||
| 331 | } | |||
| 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | |||
| 333 | SingleLockState onReceiveState=map.get("onReceive"); | |||
| 334 | if (locking(onReceiveState)) { | |||
| 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |||
| 336 | } | |||
| 337 | } | 314 | } | |
| 338 | } | 315 | } | |
| 339 | } | 316 | } | |
| 340 | } | 317 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_071 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_072 | |||
|---|---|---|---|---|
|
317 lines 12643 bytes Last modified : Mon May 14 23:48:12 2012 |
340 lines 13690 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:37.253 | 1 | //Time : 2012-04-26 20:49:39.030 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE ExpressionStmt ExpressionStmt IfStmt to IfStmt IfStmt IfStmt IfStmt = 1 | 5 | CHANGE IfStmt IfStmt IfStmt IfStmt to ExpressionStmt ExpressionStmt IfStmt = 1 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 3 | 7 | changes = 3 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 26 | /** | 26 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 28 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 31 | private Component component; | 31 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 35 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 38 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 40 | return allExitStates; | |
| 41 | } | 41 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 44 | } | 44 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 47 | } | 47 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 50 | } | 50 | } | |
| 51 | public String toString(){ | 51 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 59 | } | |
| 60 | } | 60 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 67 | ; | 67 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 71 | } | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | return null; | 75 | return null; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 80 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 83 | public static class Result { | 83 | public static class Result { | |
| 84 | private ResultType resultType; | 84 | private ResultType resultType; | |
| 85 | private String message; | 85 | private String message; | |
| 86 | public ResultType getResultType(){ | 86 | public ResultType getResultType(){ | |
| 87 | return resultType; | 87 | return resultType; | |
| 88 | } | 88 | } | |
| 89 | public String getMessage(){ | 89 | public String getMessage(){ | |
| 90 | return message; | 90 | return message; | |
| 91 | } | 91 | } | |
| 92 | public Result( ResultType rt, String msg){ | 92 | public Result( ResultType rt, String msg){ | |
| 93 | message=msg; | 93 | message=msg; | |
| 94 | resultType=rt; | 94 | resultType=rt; | |
| 95 | } | 95 | } | |
| 96 | public String toString(){ | 96 | public String toString(){ | |
| 97 | return (resultType.name() + " " + message); | 97 | return (resultType.name() + " " + message); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | /** | 100 | /** | |
| 101 | * Invoke this after the component has been analyzed | 101 | * Invoke this after the component has been analyzed | |
| 102 | * @param component | 102 | * @param component | |
| 103 | */ | 103 | */ | |
| 104 | public void createComponentSummary( Component component){ | 104 | public void createComponentSummary( Component component){ | |
| 105 | ComponentSummary componentSummary=new ComponentSummary(component); | 105 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 107 | CGNode next=it.next(); | 107 | CGNode next=it.next(); | |
| 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 109 | if (exitState != null) { | 109 | if (exitState != null) { | |
| 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 111 | componentSummary.registerNodeState(next,compoundLockState); | 111 | componentSummary.registerNodeState(next,compoundLockState); | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | allStates.add(Pair.make(component,componentSummary)); | 114 | allStates.add(Pair.make(component,componentSummary)); | |
| 115 | } | 115 | } | |
| 116 | private LockUsage getLockUsage( SingleLockState runState){ | 116 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 117 | if (runState != null) { | 117 | if (runState != null) { | |
| 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 119 | return LockUsage.LOCKING; | 119 | return LockUsage.LOCKING; | |
| 120 | } | 120 | } | |
| 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 122 | return LockUsage.EMPTY; | 122 | return LockUsage.EMPTY; | |
| 123 | } | 123 | } | |
| 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 125 | return LockUsage.FULL_UNLOCKING; | 125 | return LockUsage.FULL_UNLOCKING; | |
| 126 | } | 126 | } | |
| 127 | else if (runState.isMaybeReleased()) { | 127 | else if (runState.isMaybeReleased()) { | |
| 128 | return LockUsage.UNLOCKING; | 128 | return LockUsage.UNLOCKING; | |
| 129 | } | 129 | } | |
| 130 | else { | 130 | else { | |
| 131 | return LockUsage.UNKNOWN_STATE; | 131 | return LockUsage.UNKNOWN_STATE; | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } | |
| 134 | else { | 134 | else { | |
| 135 | return LockUsage.EMPTY; | 135 | return LockUsage.EMPTY; | |
| 136 | } | 136 | } | |
| 137 | } | 137 | } | |
| 138 | public ArrayList<Result> processResults(){ | 138 | public ArrayList<Result> processResults(){ | |
| 139 | ArrayList<Result> result=new ArrayList<Result>(); | 139 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 140 | System.out.println("\n=========================================="); | 140 | System.out.println("\n=========================================="); | |
| 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 144 | Component component=pair.fst; | 144 | Component component=pair.fst; | |
| 145 | ComponentSummary cSummary=pair.snd; | 145 | ComponentSummary cSummary=pair.snd; | |
| 146 | ComponentPolicy policy=new ComponentPolicy(component); | 146 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 147 | StringBuffer sb=new StringBuffer(); | 147 | StringBuffer sb=new StringBuffer(); | |
| 148 | boolean printComponent=false; | 148 | boolean printComponent=false; | |
| 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 150 | CGNode node=e.getKey(); | 150 | CGNode node=e.getKey(); | |
| 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 152 | boolean printMethod=false; | 152 | boolean printMethod=false; | |
| 153 | LockUsage lockUsage=LockUsage.EMPTY; | 153 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 154 | CompoundLockState compLS=e.getValue(); | 154 | CompoundLockState compLS=e.getValue(); | |
| 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 157 | WakeLockInstance wli=fs.getKey(); | 157 | WakeLockInstance wli=fs.getKey(); | |
| 158 | Set<SingleLockState> sls=fs.getValue(); | 158 | Set<SingleLockState> sls=fs.getValue(); | |
| 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 160 | lockUsage=getLockUsage(sl); | 160 | lockUsage=getLockUsage(sl); | |
| 161 | lockUsages.put(wli,lockUsage); | 161 | lockUsages.put(wli,lockUsage); | |
| 162 | if (lockUsage != LockUsage.EMPTY) { | 162 | if (lockUsage != LockUsage.EMPTY) { | |
| 163 | printMethod=true; | 163 | printMethod=true; | |
| 164 | } | 164 | } | |
| 165 | } | 165 | } | |
| 166 | if (printMethod) { | 166 | if (printMethod) { | |
| 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 168 | printComponent=true; | 168 | printComponent=true; | |
| 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 172 | WakeLockInstance key=fs.getKey(); | 172 | WakeLockInstance key=fs.getKey(); | |
| 173 | Set<SingleLockState> value=fs.getValue(); | 173 | Set<SingleLockState> value=fs.getValue(); | |
| 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 176 | } | 176 | } | |
| 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 178 | LockUsage lu=getLockUsage(mergedLS); | 178 | LockUsage lu=getLockUsage(mergedLS); | |
| 179 | if (component.isCallBack(node)) { | 179 | if (component.isCallBack(node)) { | |
| 180 | if (usageMap.containsKey(lu)) { | 180 | if (usageMap.containsKey(lu)) { | |
| 181 | usageMap.get(lu).add(Pair.make(component,node)); | 181 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 182 | } | 182 | } | |
| 183 | else { | 183 | else { | |
| 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 185 | set.add(Pair.make(component,node)); | 185 | set.add(Pair.make(component,node)); | |
| 186 | usageMap.put(lu,set); | 186 | usageMap.put(lu,set); | |
| 187 | } | 187 | } | |
| 188 | policy.addFact(node,mergedLS); | 188 | policy.addFact(node,mergedLS); | |
| 189 | } | 189 | } | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | } | 192 | } | |
| 193 | if (printComponent) { | 193 | if (printComponent) { | |
| 194 | System.out.println(component.toString() + "\n" + sb.toString()); | 194 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 195 | policy.solveFacts(); | 195 | policy.solveFacts(); | |
| 196 | componentMap.put(component,policy.getLogger()); | 196 | componentMap.put(component,policy.getLogger()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( LockUsage e : usageMap.keySet()) { | 200 | for ( LockUsage e : usageMap.keySet()) { | |
| 201 | System.out.println(e.toString()); | 201 | System.out.println(e.toString()); | |
| 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 203 | System.out.println(" " + s.toString()); | 203 | System.out.println(" " + s.toString()); | |
| 204 | } | 204 | } | |
| 205 | } | 205 | } | |
| 206 | System.out.println("==========================================\n"); | 206 | System.out.println("==========================================\n"); | |
| 207 | for ( Component e : componentMap.keySet()) { | 207 | for ( Component e : componentMap.keySet()) { | |
| 208 | Logger logger=componentMap.get(e); | 208 | Logger logger=componentMap.get(e); | |
| 209 | if (!logger.isEmpty()) { | 209 | if (!logger.isEmpty()) { | |
| 210 | System.out.println(e.toString()); | 210 | System.out.println(e.toString()); | |
| 211 | System.out.println(logger.toString()); | 211 | System.out.println(logger.toString()); | |
| 212 | System.out.println("\n"); | 212 | System.out.println("\n"); | |
| 213 | } | 213 | } | |
| 214 | result=logger.getStringList(); | 214 | result=logger.getStringList(); | |
| 215 | } | 215 | } | |
| 216 | return result; | 216 | return result; | |
| 217 | } | 217 | } | |
| 218 | public class Logger extends ArrayList<Result> { | 218 | public class Logger extends ArrayList<Result> { | |
| 219 | private static final long serialVersionUID=4402714524487791090L; | 219 | private static final long serialVersionUID=4402714524487791090L; | |
| 220 | public void output(){ | 220 | public void output(){ | |
| 221 | for ( Result r : this) { | 221 | for ( Result r : this) { | |
| 222 | System.out.println(" " + r.getResultType().toString()); | 222 | System.out.println(" " + r.getResultType().toString()); | |
| 223 | } | 223 | } | |
| 224 | } | 224 | } | |
| 225 | public ArrayList<Result> getStringList(){ | 225 | public ArrayList<Result> getStringList(){ | |
| 226 | return this; | 226 | return this; | |
| 227 | } | 227 | } | |
| 228 | public String toString(){ | 228 | public String toString(){ | |
| 229 | StringBuffer result=new StringBuffer(); | 229 | StringBuffer result=new StringBuffer(); | |
| 230 | for ( Result r : this) { | 230 | for ( Result r : this) { | |
| 231 | result.append(r.toString() + "\n"); | 231 | result.append(r.toString() + "\n"); | |
| 232 | } | 232 | } | |
| 233 | return result.toString(); | 233 | return result.toString(); | |
| 234 | } | 234 | } | |
| 235 | } | 235 | } | |
| 236 | public class ComponentPolicy { | 236 | public class ComponentPolicy { | |
| 237 | private Component component; | 237 | private Component component; | |
| 238 | public ComponentPolicy( Component component){ | 238 | public ComponentPolicy( Component component){ | |
| 239 | this.component=component; | 239 | this.component=component; | |
| 240 | map=new HashMap<String,SingleLockState>(); | 240 | map=new HashMap<String,SingleLockState>(); | |
| 241 | logger=new Logger(); | 241 | logger=new Logger(); | |
| 242 | } | 242 | } | |
| 243 | private HashMap<String,SingleLockState> map; | 243 | private HashMap<String,SingleLockState> map; | |
| 244 | public void addFact( CGNode n, SingleLockState st){ | 244 | public void addFact( CGNode n, SingleLockState st){ | |
| 245 | map.put(n.getMethod().getName().toString(),st); | 245 | map.put(n.getMethod().getName().toString(),st); | |
| 246 | } | 246 | } | |
| 247 | private boolean unlocking( SingleLockState state){ | 247 | private boolean unlocking( SingleLockState state){ | |
| 248 | return (strongUnlocking(state) || weakUnlocking(state)); | 248 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 249 | } | 249 | } | |
| 250 | private boolean strongUnlocking( SingleLockState state){ | 250 | private boolean strongUnlocking( SingleLockState state){ | |
| 251 | if (state != null) { | 251 | if (state != null) { | |
| 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 253 | } | 253 | } | |
| 254 | return true; | 254 | return true; | |
| 255 | } | 255 | } | |
| 256 | private boolean weakUnlocking( SingleLockState state){ | 256 | private boolean weakUnlocking( SingleLockState state){ | |
| 257 | if (state != null) { | 257 | if (state != null) { | |
| 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 259 | } | 259 | } | |
| 260 | return true; | 260 | return true; | |
| 261 | } | 261 | } | |
| 262 | private boolean locking( SingleLockState onCreateState){ | 262 | private boolean locking( SingleLockState onCreateState){ | |
| 263 | if (onCreateState != null) { | 263 | if (onCreateState != null) { | |
| 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 265 | } | 265 | } | |
| 266 | return false; | 266 | return false; | |
| 267 | } | 267 | } | |
| 268 | private Logger logger; | 268 | private Logger logger; | |
| 269 | private void logNote( Result result){ | 269 | private void logNote( Result result){ | |
| 270 | logger.add(result); | 270 | logger.add(result); | |
| 271 | } | 271 | } | |
| 272 | public Logger getLogger(){ | 272 | public Logger getLogger(){ | |
| 273 | return logger; | 273 | return logger; | |
| 274 | } | 274 | } | |
| 275 | private SingleLockState getServiceOnStart(){ | 275 | private SingleLockState getServiceOnStart(){ | |
| 276 | SingleLockState onStart=map.get("onStart"); | 276 | SingleLockState onStart=map.get("onStart"); | |
| 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 278 | if (onStartCommand == null) { | 278 | if (onStartCommand == null) { | |
| 279 | return onStart; | 279 | return onStart; | |
| 280 | } | 280 | } | |
| 281 | else { | 281 | else { | |
| 282 | return onStartCommand; | 282 | return onStartCommand; | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | /** | 285 | /** | |
| 286 | * TODO: make sure the same lock is locked and unlocked... | 286 | * TODO: make sure the same lock is locked and unlocked... | |
| 287 | */ | 287 | */ | |
| 288 | public void solveFacts(){ | 288 | public void solveFacts(){ | |
| 289 | if (component.getComponentType().equals("Activity")) { | 289 | if (component.getComponentType().equals("Activity")) { | |
| 290 | SingleLockState onCreateState=map.get("onCreate"); | 290 | SingleLockState onCreateState=map.get("onCreate"); | |
| 291 | if (locking(onCreateState)) { | 291 | if (locking(onCreateState)) { | |
| 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 293 | } | 293 | } | |
| 294 | SingleLockState onStartState=map.get("onStart"); | 294 | SingleLockState onStartState=map.get("onStart"); | |
| 295 | if (locking(onStartState)) { | 295 | if (locking(onStartState)) { | |
| 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 297 | } | 297 | } | |
| 298 | SingleLockState onRestartState=map.get("onRestart"); | 298 | SingleLockState onRestartState=map.get("onRestart"); | |
| 299 | if (locking(onRestartState)) { | 299 | if (locking(onRestartState)) { | |
| 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | SingleLockState onPauseState=map.get("onPause"); | 302 | SingleLockState onPauseState=map.get("onPause"); | |
| 303 | if (!unlocking(onPauseState)) { | 303 | if (!unlocking(onPauseState)) { | |
| 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 305 | } | 305 | } | |
| 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | SingleLockState onStartState=getServiceOnStart(); | 310 | if (component.getComponentType().equals("Service")) { | |
| 311 | SingleLockState onDestroyState=map.get("onDestroy"); | 311 | SingleLockState onStartState=getServiceOnStart(); | |
| 312 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 312 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 313 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |||
| 315 | } | |||
| 316 | if (weakUnlocking(onDestroyState) && !str) { | |||
| 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |||
| 318 | } | |||
| 319 | } | |||
| 320 | if (component.getComponentType().equals("RunnableThread")) { | |||
| 321 | SingleLockState runState=map.get("run"); | |||
| 322 | if (locking(runState)) { | |||
| 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |||
| 324 | } | |||
| 325 | } | |||
| 326 | if (component.getComponentType().equals("Handler")) { | |||
| 327 | SingleLockState handleState=map.get("handleMessage"); | |||
| 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |||
| 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |||
| 330 | } | |||
| 331 | } | |||
| 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | |||
| 333 | SingleLockState onReceiveState=map.get("onReceive"); | |||
| 334 | if (locking(onReceiveState)) { | |||
| 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |||
| 336 | } | |||
| 314 | } | 337 | } | |
| 315 | } | 338 | } | |
| 316 | } | 339 | } | |
| 317 | } | 340 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_072 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_073 | |||
|---|---|---|---|---|
|
340 lines 13690 bytes Last modified : Mon May 14 23:48:12 2012 |
340 lines 13658 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:39.030 | 1 | //Time : 2012-04-26 20:49:40.301 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt IfStmt IfStmt IfStmt to ExpressionStmt ExpressionStmt IfStmt = 1 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 3 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 26 | /** | 26 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 28 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 31 | private Component component; | 31 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 35 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 38 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 40 | return allExitStates; | |
| 41 | } | 41 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 44 | } | 44 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 47 | } | 47 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 50 | } | 50 | } | |
| 51 | public String toString(){ | 51 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 59 | } | |
| 60 | } | 60 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 67 | ; | 67 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 71 | } | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | return null; | 75 | return null; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 80 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 83 | public static class Result { | 83 | public static class Result { | |
| 84 | private ResultType resultType; | 84 | private ResultType resultType; | |
| 85 | private String message; | 85 | private String message; | |
| 86 | public ResultType getResultType(){ | 86 | public ResultType getResultType(){ | |
| 87 | return resultType; | 87 | return resultType; | |
| 88 | } | 88 | } | |
| 89 | public String getMessage(){ | 89 | public String getMessage(){ | |
| 90 | return message; | 90 | return message; | |
| 91 | } | 91 | } | |
| 92 | public Result( ResultType rt, String msg){ | 92 | public Result( ResultType rt, String msg){ | |
| 93 | message=msg; | 93 | message=msg; | |
| 94 | resultType=rt; | 94 | resultType=rt; | |
| 95 | } | 95 | } | |
| 96 | public String toString(){ | 96 | public String toString(){ | |
| 97 | return (resultType.name() + " " + message); | 97 | return (resultType.name() + " " + message); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | /** | 100 | /** | |
| 101 | * Invoke this after the component has been analyzed | 101 | * Invoke this after the component has been analyzed | |
| 102 | * @param component | 102 | * @param component | |
| 103 | */ | 103 | */ | |
| 104 | public void createComponentSummary( Component component){ | 104 | public void createComponentSummary( Component component){ | |
| 105 | ComponentSummary componentSummary=new ComponentSummary(component); | 105 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 107 | CGNode next=it.next(); | 107 | CGNode next=it.next(); | |
| 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 109 | if (exitState != null) { | 109 | if (exitState != null) { | |
| 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 111 | componentSummary.registerNodeState(next,compoundLockState); | 111 | componentSummary.registerNodeState(next,compoundLockState); | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | allStates.add(Pair.make(component,componentSummary)); | 114 | allStates.add(Pair.make(component,componentSummary)); | |
| 115 | } | 115 | } | |
| 116 | private LockUsage getLockUsage( SingleLockState runState){ | 116 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 117 | if (runState != null) { | 117 | if (runState != null) { | |
| 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 119 | return LockUsage.LOCKING; | 119 | return LockUsage.LOCKING; | |
| 120 | } | 120 | } | |
| 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 122 | return LockUsage.EMPTY; | 122 | return LockUsage.EMPTY; | |
| 123 | } | 123 | } | |
| 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 125 | return LockUsage.FULL_UNLOCKING; | 125 | return LockUsage.FULL_UNLOCKING; | |
| 126 | } | 126 | } | |
| 127 | else if (runState.isMaybeReleased()) { | 127 | else if (runState.isMaybeReleased()) { | |
| 128 | return LockUsage.UNLOCKING; | 128 | return LockUsage.UNLOCKING; | |
| 129 | } | 129 | } | |
| 130 | else { | 130 | else { | |
| 131 | return LockUsage.UNKNOWN_STATE; | 131 | return LockUsage.UNKNOWN_STATE; | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } | |
| 134 | else { | 134 | else { | |
| 135 | return LockUsage.EMPTY; | 135 | return LockUsage.EMPTY; | |
| 136 | } | 136 | } | |
| 137 | } | 137 | } | |
| 138 | public ArrayList<Result> processResults(){ | 138 | public ArrayList<Result> processResults(){ | |
| 139 | ArrayList<Result> result=new ArrayList<Result>(); | 139 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 140 | System.out.println("\n=========================================="); | 140 | System.out.println("\n=========================================="); | |
| 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 144 | Component component=pair.fst; | 144 | Component component=pair.fst; | |
| 145 | ComponentSummary cSummary=pair.snd; | 145 | ComponentSummary cSummary=pair.snd; | |
| 146 | ComponentPolicy policy=new ComponentPolicy(component); | 146 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 147 | StringBuffer sb=new StringBuffer(); | 147 | StringBuffer sb=new StringBuffer(); | |
| 148 | boolean printComponent=false; | 148 | boolean printComponent=false; | |
| 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 150 | CGNode node=e.getKey(); | 150 | CGNode node=e.getKey(); | |
| 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 152 | boolean printMethod=false; | 152 | boolean printMethod=false; | |
| 153 | LockUsage lockUsage=LockUsage.EMPTY; | 153 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 154 | CompoundLockState compLS=e.getValue(); | 154 | CompoundLockState compLS=e.getValue(); | |
| 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 157 | WakeLockInstance wli=fs.getKey(); | 157 | WakeLockInstance wli=fs.getKey(); | |
| 158 | Set<SingleLockState> sls=fs.getValue(); | 158 | Set<SingleLockState> sls=fs.getValue(); | |
| 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 160 | lockUsage=getLockUsage(sl); | 160 | lockUsage=getLockUsage(sl); | |
| 161 | lockUsages.put(wli,lockUsage); | 161 | lockUsages.put(wli,lockUsage); | |
| 162 | if (lockUsage != LockUsage.EMPTY) { | 162 | if (lockUsage != LockUsage.EMPTY) { | |
| 163 | printMethod=true; | 163 | printMethod=true; | |
| 164 | } | 164 | } | |
| 165 | } | 165 | } | |
| 166 | if (printMethod) { | 166 | if (printMethod) { | |
| 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 168 | printComponent=true; | 168 | printComponent=true; | |
| 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 172 | WakeLockInstance key=fs.getKey(); | 172 | WakeLockInstance key=fs.getKey(); | |
| 173 | Set<SingleLockState> value=fs.getValue(); | 173 | Set<SingleLockState> value=fs.getValue(); | |
| 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 176 | } | 176 | } | |
| 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 178 | LockUsage lu=getLockUsage(mergedLS); | 178 | LockUsage lu=getLockUsage(mergedLS); | |
| 179 | if (component.isCallBack(node)) { | 179 | if (component.isCallBack(node)) { | |
| 180 | if (usageMap.containsKey(lu)) { | 180 | if (usageMap.containsKey(lu)) { | |
| 181 | usageMap.get(lu).add(Pair.make(component,node)); | 181 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 182 | } | 182 | } | |
| 183 | else { | 183 | else { | |
| 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 185 | set.add(Pair.make(component,node)); | 185 | set.add(Pair.make(component,node)); | |
| 186 | usageMap.put(lu,set); | 186 | usageMap.put(lu,set); | |
| 187 | } | 187 | } | |
| 188 | policy.addFact(node,mergedLS); | 188 | policy.addFact(node,mergedLS); | |
| 189 | } | 189 | } | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | } | 192 | } | |
| 193 | if (printComponent) { | 193 | if (printComponent) { | |
| 194 | System.out.println(component.toString() + "\n" + sb.toString()); | 194 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 195 | policy.solveFacts(); | 195 | policy.solveFacts(); | |
| 196 | componentMap.put(component,policy.getLogger()); | 196 | componentMap.put(component,policy.getLogger()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( LockUsage e : usageMap.keySet()) { | 200 | for ( LockUsage e : usageMap.keySet()) { | |
| 201 | System.out.println(e.toString()); | 201 | System.out.println(e.toString()); | |
| 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 203 | System.out.println(" " + s.toString()); | 203 | System.out.println(" " + s.toString()); | |
| 204 | } | 204 | } | |
| 205 | } | 205 | } | |
| 206 | System.out.println("==========================================\n"); | 206 | System.out.println("==========================================\n"); | |
| 207 | for ( Component e : componentMap.keySet()) { | 207 | for ( Component e : componentMap.keySet()) { | |
| 208 | Logger logger=componentMap.get(e); | 208 | Logger logger=componentMap.get(e); | |
| 209 | if (!logger.isEmpty()) { | 209 | if (!logger.isEmpty()) { | |
| 210 | System.out.println(e.toString()); | 210 | System.out.println(e.toString()); | |
| 211 | System.out.println(logger.toString()); | 211 | System.out.println(logger.toString()); | |
| 212 | System.out.println("\n"); | 212 | System.out.println("\n"); | |
| 213 | } | 213 | } | |
| 214 | result=logger.getStringList(); | 214 | result=logger.getStringList(); | |
| 215 | } | 215 | } | |
| 216 | return result; | 216 | return result; | |
| 217 | } | 217 | } | |
| 218 | public class Logger extends ArrayList<Result> { | 218 | public class Logger extends ArrayList<Result> { | |
| 219 | private static final long serialVersionUID=4402714524487791090L; | 219 | private static final long serialVersionUID=4402714524487791090L; | |
| 220 | public void output(){ | 220 | public void output(){ | |
| 221 | for ( Result r : this) { | 221 | for ( Result r : this) { | |
| 222 | System.out.println(" " + r.getResultType().toString()); | 222 | System.out.println(" " + r.getResultType().toString()); | |
| 223 | } | 223 | } | |
| 224 | } | 224 | } | |
| 225 | public ArrayList<Result> getStringList(){ | 225 | public ArrayList<Result> getStringList(){ | |
| 226 | return this; | 226 | return this; | |
| 227 | } | 227 | } | |
| 228 | public String toString(){ | 228 | public String toString(){ | |
| 229 | StringBuffer result=new StringBuffer(); | 229 | StringBuffer result=new StringBuffer(); | |
| 230 | for ( Result r : this) { | 230 | for ( Result r : this) { | |
| 231 | result.append(r.toString() + "\n"); | 231 | result.append(r.toString() + "\n"); | |
| 232 | } | 232 | } | |
| 233 | return result.toString(); | 233 | return result.toString(); | |
| 234 | } | 234 | } | |
| 235 | } | 235 | } | |
| 236 | public class ComponentPolicy { | 236 | public class ComponentPolicy { | |
| 237 | private Component component; | 237 | private Component component; | |
| 238 | public ComponentPolicy( Component component){ | 238 | public ComponentPolicy( Component component){ | |
| 239 | this.component=component; | 239 | this.component=component; | |
| 240 | map=new HashMap<String,SingleLockState>(); | 240 | map=new HashMap<String,SingleLockState>(); | |
| 241 | logger=new Logger(); | 241 | logger=new Logger(); | |
| 242 | } | 242 | } | |
| 243 | private HashMap<String,SingleLockState> map; | 243 | private HashMap<String,SingleLockState> map; | |
| 244 | public void addFact( CGNode n, SingleLockState st){ | 244 | public void addFact( CGNode n, SingleLockState st){ | |
| 245 | map.put(n.getMethod().getName().toString(),st); | 245 | map.put(n.getMethod().getName().toString(),st); | |
| 246 | } | 246 | } | |
| 247 | private boolean unlocking( SingleLockState state){ | 247 | private boolean unlocking( SingleLockState state){ | |
| 248 | return (strongUnlocking(state) || weakUnlocking(state)); | 248 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 249 | } | 249 | } | |
| 250 | private boolean strongUnlocking( SingleLockState state){ | 250 | private boolean strongUnlocking( SingleLockState state){ | |
| 251 | if (state != null) { | 251 | if (state != null) { | |
| 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 253 | } | 253 | } | |
| 254 | return true; | 254 | return true; | |
| 255 | } | 255 | } | |
| 256 | private boolean weakUnlocking( SingleLockState state){ | 256 | private boolean weakUnlocking( SingleLockState state){ | |
| 257 | if (state != null) { | 257 | if (state != null) { | |
| 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 259 | } | 259 | } | |
| 260 | return true; | 260 | return true; | |
| 261 | } | 261 | } | |
| 262 | private boolean locking( SingleLockState onCreateState){ | 262 | private boolean locking( SingleLockState onCreateState){ | |
| 263 | if (onCreateState != null) { | 263 | if (onCreateState != null) { | |
| 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 265 | } | 265 | } | |
| 266 | return false; | 266 | return false; | |
| 267 | } | 267 | } | |
| 268 | private Logger logger; | 268 | private Logger logger; | |
| 269 | private void logNote( Result result){ | 269 | private void logNote( Result result){ | |
| 270 | logger.add(result); | 270 | logger.add(result); | |
| 271 | } | 271 | } | |
| 272 | public Logger getLogger(){ | 272 | public Logger getLogger(){ | |
| 273 | return logger; | 273 | return logger; | |
| 274 | } | 274 | } | |
| 275 | private SingleLockState getServiceOnStart(){ | 275 | private SingleLockState getServiceOnStart(){ | |
| 276 | SingleLockState onStart=map.get("onStart"); | 276 | SingleLockState onStart=map.get("onStart"); | |
| 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 278 | if (onStartCommand == null) { | 278 | if (onStartCommand == null) { | |
| 279 | return onStart; | 279 | return onStart; | |
| 280 | } | 280 | } | |
| 281 | else { | 281 | else { | |
| 282 | return onStartCommand; | 282 | return onStartCommand; | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | /** | 285 | /** | |
| 286 | * TODO: make sure the same lock is locked and unlocked... | 286 | * TODO: make sure the same lock is locked and unlocked... | |
| 287 | */ | 287 | */ | |
| 288 | public void solveFacts(){ | 288 | public void solveFacts(){ | |
| 289 | if (component.getComponentType().equals("Activity")) { | 289 | if (component.getComponentType().equals("Activity")) { | |
| 290 | SingleLockState onCreateState=map.get("onCreate"); | 290 | SingleLockState onCreateState=map.get("onCreate"); | |
| 291 | if (locking(onCreateState)) { | 291 | if (locking(onCreateState)) { | |
| 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 293 | } | 293 | } | |
| 294 | SingleLockState onStartState=map.get("onStart"); | 294 | SingleLockState onStartState=map.get("onStart"); | |
| 295 | if (locking(onStartState)) { | 295 | if (locking(onStartState)) { | |
| 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 297 | } | 297 | } | |
| 298 | SingleLockState onRestartState=map.get("onRestart"); | 298 | SingleLockState onRestartState=map.get("onRestart"); | |
| 299 | if (locking(onRestartState)) { | 299 | if (locking(onRestartState)) { | |
| 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | SingleLockState onPauseState=map.get("onPause"); | 302 | SingleLockState onPauseState=map.get("onPause"); | |
| 303 | if (!unlocking(onPauseState)) { | 303 | if (!unlocking(onPauseState)) { | |
| 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 305 | } | 305 | } | |
| 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("Service")) { | 310 | if (component.getComponentType().equals("Service")) { | |
| 311 | SingleLockState onStartState=getServiceOnStart(); | 311 | SingleLockState onStartState=getServiceOnStart(); | |
| 312 | SingleLockState onDestroyState=map.get("onDestroy"); | 312 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 315 | } | 315 | } | |
| 316 | if (weakUnlocking(onDestroyState) && !str) { | 316 | if (weakUnlocking(onDestroyState) && !strongUnlocking(state)) { | |
| 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | if (component.getComponentType().equals("RunnableThread")) { | 320 | if (component.getComponentType().equals("RunnableThread")) { | |
| 321 | SingleLockState runState=map.get("run"); | 321 | SingleLockState runState=map.get("run"); | |
| 322 | if (locking(runState)) { | 322 | if (locking(runState)) { | |
| 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } | |
| 326 | if (component.getComponentType().equals("Handler")) { | 326 | if (component.getComponentType().equals("Handler")) { | |
| 327 | SingleLockState handleState=map.get("handleMessage"); | 327 | SingleLockState handleState=map.get("handleMessage"); | |
| 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 333 | SingleLockState onReceiveState=map.get("onReceive"); | 333 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 334 | if (locking(onReceiveState)) { | 334 | if (locking(onReceiveState)) { | |
| 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 336 | } | 336 | } | |
| 337 | } | 337 | } | |
| 338 | } | 338 | } | |
| 339 | } | 339 | } | |
| 340 | } | 340 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_073 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_074 | |||
|---|---|---|---|---|
|
340 lines 13658 bytes Last modified : Mon May 14 23:48:12 2012 |
340 lines 13667 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:40.301 | 1 | //Time : 2012-04-26 20:49:44.084 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | CHANGE IfStmt to IfStmt = 2 | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 7 | changes = 4 | 7 | changes = 4 | |
| 8 | changes to method solveFacts = 1 | 8 | changes to method solveFacts = 1 | |
| 9 | private/protected method declarations = 1 | 9 | private/protected method declarations = 1 | |
| 10 | */package energy.analysis; | 10 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 11 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 12 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 13 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 14 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 15 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 16 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 17 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 18 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 19 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 21 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 22 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 23 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 24 | import energy.interproc.SingleLockState; | |
| 25 | public class AnalysisResults { | 25 | public class AnalysisResults { | |
| 26 | /** | 26 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 27 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 28 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 30 | public class ComponentSummary { | |
| 31 | private Component component; | 31 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 34 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 35 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 38 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 40 | return allExitStates; | |
| 41 | } | 41 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 43 | allExitStates.put(n,st); | |
| 44 | } | 44 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 46 | callBackExitStates.put(cb,st); | |
| 47 | } | 47 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 48 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 49 | return allExitStates.get(method); | |
| 50 | } | 50 | } | |
| 51 | public String toString(){ | 51 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 52 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 54 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 55 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 56 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 57 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 58 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 59 | } | |
| 60 | } | 60 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 62 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 63 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 64 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 65 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 66 | String name=cb.getName(); | |
| 67 | ; | 67 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 68 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 69 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 71 | } | |
| 72 | } | 72 | } | |
| 73 | } | 73 | } | |
| 74 | } | 74 | } | |
| 75 | return null; | 75 | return null; | |
| 76 | } | 76 | } | |
| 77 | } | 77 | } | |
| 78 | public AnalysisResults(){ | 78 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 80 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 83 | public static class Result { | 83 | public static class Result { | |
| 84 | private ResultType resultType; | 84 | private ResultType resultType; | |
| 85 | private String message; | 85 | private String message; | |
| 86 | public ResultType getResultType(){ | 86 | public ResultType getResultType(){ | |
| 87 | return resultType; | 87 | return resultType; | |
| 88 | } | 88 | } | |
| 89 | public String getMessage(){ | 89 | public String getMessage(){ | |
| 90 | return message; | 90 | return message; | |
| 91 | } | 91 | } | |
| 92 | public Result( ResultType rt, String msg){ | 92 | public Result( ResultType rt, String msg){ | |
| 93 | message=msg; | 93 | message=msg; | |
| 94 | resultType=rt; | 94 | resultType=rt; | |
| 95 | } | 95 | } | |
| 96 | public String toString(){ | 96 | public String toString(){ | |
| 97 | return (resultType.name() + " " + message); | 97 | return (resultType.name() + " " + message); | |
| 98 | } | 98 | } | |
| 99 | } | 99 | } | |
| 100 | /** | 100 | /** | |
| 101 | * Invoke this after the component has been analyzed | 101 | * Invoke this after the component has been analyzed | |
| 102 | * @param component | 102 | * @param component | |
| 103 | */ | 103 | */ | |
| 104 | public void createComponentSummary( Component component){ | 104 | public void createComponentSummary( Component component){ | |
| 105 | ComponentSummary componentSummary=new ComponentSummary(component); | 105 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 107 | CGNode next=it.next(); | 107 | CGNode next=it.next(); | |
| 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 109 | if (exitState != null) { | 109 | if (exitState != null) { | |
| 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 111 | componentSummary.registerNodeState(next,compoundLockState); | 111 | componentSummary.registerNodeState(next,compoundLockState); | |
| 112 | } | 112 | } | |
| 113 | } | 113 | } | |
| 114 | allStates.add(Pair.make(component,componentSummary)); | 114 | allStates.add(Pair.make(component,componentSummary)); | |
| 115 | } | 115 | } | |
| 116 | private LockUsage getLockUsage( SingleLockState runState){ | 116 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 117 | if (runState != null) { | 117 | if (runState != null) { | |
| 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 119 | return LockUsage.LOCKING; | 119 | return LockUsage.LOCKING; | |
| 120 | } | 120 | } | |
| 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 122 | return LockUsage.EMPTY; | 122 | return LockUsage.EMPTY; | |
| 123 | } | 123 | } | |
| 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 125 | return LockUsage.FULL_UNLOCKING; | 125 | return LockUsage.FULL_UNLOCKING; | |
| 126 | } | 126 | } | |
| 127 | else if (runState.isMaybeReleased()) { | 127 | else if (runState.isMaybeReleased()) { | |
| 128 | return LockUsage.UNLOCKING; | 128 | return LockUsage.UNLOCKING; | |
| 129 | } | 129 | } | |
| 130 | else { | 130 | else { | |
| 131 | return LockUsage.UNKNOWN_STATE; | 131 | return LockUsage.UNKNOWN_STATE; | |
| 132 | } | 132 | } | |
| 133 | } | 133 | } | |
| 134 | else { | 134 | else { | |
| 135 | return LockUsage.EMPTY; | 135 | return LockUsage.EMPTY; | |
| 136 | } | 136 | } | |
| 137 | } | 137 | } | |
| 138 | public ArrayList<Result> processResults(){ | 138 | public ArrayList<Result> processResults(){ | |
| 139 | ArrayList<Result> result=new ArrayList<Result>(); | 139 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 140 | System.out.println("\n=========================================="); | 140 | System.out.println("\n=========================================="); | |
| 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 144 | Component component=pair.fst; | 144 | Component component=pair.fst; | |
| 145 | ComponentSummary cSummary=pair.snd; | 145 | ComponentSummary cSummary=pair.snd; | |
| 146 | ComponentPolicy policy=new ComponentPolicy(component); | 146 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 147 | StringBuffer sb=new StringBuffer(); | 147 | StringBuffer sb=new StringBuffer(); | |
| 148 | boolean printComponent=false; | 148 | boolean printComponent=false; | |
| 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 150 | CGNode node=e.getKey(); | 150 | CGNode node=e.getKey(); | |
| 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 152 | boolean printMethod=false; | 152 | boolean printMethod=false; | |
| 153 | LockUsage lockUsage=LockUsage.EMPTY; | 153 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 154 | CompoundLockState compLS=e.getValue(); | 154 | CompoundLockState compLS=e.getValue(); | |
| 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 157 | WakeLockInstance wli=fs.getKey(); | 157 | WakeLockInstance wli=fs.getKey(); | |
| 158 | Set<SingleLockState> sls=fs.getValue(); | 158 | Set<SingleLockState> sls=fs.getValue(); | |
| 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 160 | lockUsage=getLockUsage(sl); | 160 | lockUsage=getLockUsage(sl); | |
| 161 | lockUsages.put(wli,lockUsage); | 161 | lockUsages.put(wli,lockUsage); | |
| 162 | if (lockUsage != LockUsage.EMPTY) { | 162 | if (lockUsage != LockUsage.EMPTY) { | |
| 163 | printMethod=true; | 163 | printMethod=true; | |
| 164 | } | 164 | } | |
| 165 | } | 165 | } | |
| 166 | if (printMethod) { | 166 | if (printMethod) { | |
| 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 168 | printComponent=true; | 168 | printComponent=true; | |
| 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 172 | WakeLockInstance key=fs.getKey(); | 172 | WakeLockInstance key=fs.getKey(); | |
| 173 | Set<SingleLockState> value=fs.getValue(); | 173 | Set<SingleLockState> value=fs.getValue(); | |
| 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 176 | } | 176 | } | |
| 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 178 | LockUsage lu=getLockUsage(mergedLS); | 178 | LockUsage lu=getLockUsage(mergedLS); | |
| 179 | if (component.isCallBack(node)) { | 179 | if (component.isCallBack(node)) { | |
| 180 | if (usageMap.containsKey(lu)) { | 180 | if (usageMap.containsKey(lu)) { | |
| 181 | usageMap.get(lu).add(Pair.make(component,node)); | 181 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 182 | } | 182 | } | |
| 183 | else { | 183 | else { | |
| 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 185 | set.add(Pair.make(component,node)); | 185 | set.add(Pair.make(component,node)); | |
| 186 | usageMap.put(lu,set); | 186 | usageMap.put(lu,set); | |
| 187 | } | 187 | } | |
| 188 | policy.addFact(node,mergedLS); | 188 | policy.addFact(node,mergedLS); | |
| 189 | } | 189 | } | |
| 190 | } | 190 | } | |
| 191 | } | 191 | } | |
| 192 | } | 192 | } | |
| 193 | if (printComponent) { | 193 | if (printComponent) { | |
| 194 | System.out.println(component.toString() + "\n" + sb.toString()); | 194 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 195 | policy.solveFacts(); | 195 | policy.solveFacts(); | |
| 196 | componentMap.put(component,policy.getLogger()); | 196 | componentMap.put(component,policy.getLogger()); | |
| 197 | } | 197 | } | |
| 198 | } | 198 | } | |
| 199 | System.out.println("==========================================\n"); | 199 | System.out.println("==========================================\n"); | |
| 200 | for ( LockUsage e : usageMap.keySet()) { | 200 | for ( LockUsage e : usageMap.keySet()) { | |
| 201 | System.out.println(e.toString()); | 201 | System.out.println(e.toString()); | |
| 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 203 | System.out.println(" " + s.toString()); | 203 | System.out.println(" " + s.toString()); | |
| 204 | } | 204 | } | |
| 205 | } | 205 | } | |
| 206 | System.out.println("==========================================\n"); | 206 | System.out.println("==========================================\n"); | |
| 207 | for ( Component e : componentMap.keySet()) { | 207 | for ( Component e : componentMap.keySet()) { | |
| 208 | Logger logger=componentMap.get(e); | 208 | Logger logger=componentMap.get(e); | |
| 209 | if (!logger.isEmpty()) { | 209 | if (!logger.isEmpty()) { | |
| 210 | System.out.println(e.toString()); | 210 | System.out.println(e.toString()); | |
| 211 | System.out.println(logger.toString()); | 211 | System.out.println(logger.toString()); | |
| 212 | System.out.println("\n"); | 212 | System.out.println("\n"); | |
| 213 | } | 213 | } | |
| 214 | result=logger.getStringList(); | 214 | result=logger.getStringList(); | |
| 215 | } | 215 | } | |
| 216 | return result; | 216 | return result; | |
| 217 | } | 217 | } | |
| 218 | public class Logger extends ArrayList<Result> { | 218 | public class Logger extends ArrayList<Result> { | |
| 219 | private static final long serialVersionUID=4402714524487791090L; | 219 | private static final long serialVersionUID=4402714524487791090L; | |
| 220 | public void output(){ | 220 | public void output(){ | |
| 221 | for ( Result r : this) { | 221 | for ( Result r : this) { | |
| 222 | System.out.println(" " + r.getResultType().toString()); | 222 | System.out.println(" " + r.getResultType().toString()); | |
| 223 | } | 223 | } | |
| 224 | } | 224 | } | |
| 225 | public ArrayList<Result> getStringList(){ | 225 | public ArrayList<Result> getStringList(){ | |
| 226 | return this; | 226 | return this; | |
| 227 | } | 227 | } | |
| 228 | public String toString(){ | 228 | public String toString(){ | |
| 229 | StringBuffer result=new StringBuffer(); | 229 | StringBuffer result=new StringBuffer(); | |
| 230 | for ( Result r : this) { | 230 | for ( Result r : this) { | |
| 231 | result.append(r.toString() + "\n"); | 231 | result.append(r.toString() + "\n"); | |
| 232 | } | 232 | } | |
| 233 | return result.toString(); | 233 | return result.toString(); | |
| 234 | } | 234 | } | |
| 235 | } | 235 | } | |
| 236 | public class ComponentPolicy { | 236 | public class ComponentPolicy { | |
| 237 | private Component component; | 237 | private Component component; | |
| 238 | public ComponentPolicy( Component component){ | 238 | public ComponentPolicy( Component component){ | |
| 239 | this.component=component; | 239 | this.component=component; | |
| 240 | map=new HashMap<String,SingleLockState>(); | 240 | map=new HashMap<String,SingleLockState>(); | |
| 241 | logger=new Logger(); | 241 | logger=new Logger(); | |
| 242 | } | 242 | } | |
| 243 | private HashMap<String,SingleLockState> map; | 243 | private HashMap<String,SingleLockState> map; | |
| 244 | public void addFact( CGNode n, SingleLockState st){ | 244 | public void addFact( CGNode n, SingleLockState st){ | |
| 245 | map.put(n.getMethod().getName().toString(),st); | 245 | map.put(n.getMethod().getName().toString(),st); | |
| 246 | } | 246 | } | |
| 247 | private boolean unlocking( SingleLockState state){ | 247 | private boolean unlocking( SingleLockState state){ | |
| 248 | return (strongUnlocking(state) || weakUnlocking(state)); | 248 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 249 | } | 249 | } | |
| 250 | private boolean strongUnlocking( SingleLockState state){ | 250 | private boolean strongUnlocking( SingleLockState state){ | |
| 251 | if (state != null) { | 251 | if (state != null) { | |
| 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 253 | } | 253 | } | |
| 254 | return true; | 254 | return true; | |
| 255 | } | 255 | } | |
| 256 | private boolean weakUnlocking( SingleLockState state){ | 256 | private boolean weakUnlocking( SingleLockState state){ | |
| 257 | if (state != null) { | 257 | if (state != null) { | |
| 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 259 | } | 259 | } | |
| 260 | return true; | 260 | return true; | |
| 261 | } | 261 | } | |
| 262 | private boolean locking( SingleLockState onCreateState){ | 262 | private boolean locking( SingleLockState onCreateState){ | |
| 263 | if (onCreateState != null) { | 263 | if (onCreateState != null) { | |
| 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 265 | } | 265 | } | |
| 266 | return false; | 266 | return false; | |
| 267 | } | 267 | } | |
| 268 | private Logger logger; | 268 | private Logger logger; | |
| 269 | private void logNote( Result result){ | 269 | private void logNote( Result result){ | |
| 270 | logger.add(result); | 270 | logger.add(result); | |
| 271 | } | 271 | } | |
| 272 | public Logger getLogger(){ | 272 | public Logger getLogger(){ | |
| 273 | return logger; | 273 | return logger; | |
| 274 | } | 274 | } | |
| 275 | private SingleLockState getServiceOnStart(){ | 275 | private SingleLockState getServiceOnStart(){ | |
| 276 | SingleLockState onStart=map.get("onStart"); | 276 | SingleLockState onStart=map.get("onStart"); | |
| 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 278 | if (onStartCommand == null) { | 278 | if (onStartCommand == null) { | |
| 279 | return onStart; | 279 | return onStart; | |
| 280 | } | 280 | } | |
| 281 | else { | 281 | else { | |
| 282 | return onStartCommand; | 282 | return onStartCommand; | |
| 283 | } | 283 | } | |
| 284 | } | 284 | } | |
| 285 | /** | 285 | /** | |
| 286 | * TODO: make sure the same lock is locked and unlocked... | 286 | * TODO: make sure the same lock is locked and unlocked... | |
| 287 | */ | 287 | */ | |
| 288 | public void solveFacts(){ | 288 | public void solveFacts(){ | |
| 289 | if (component.getComponentType().equals("Activity")) { | 289 | if (component.getComponentType().equals("Activity")) { | |
| 290 | SingleLockState onCreateState=map.get("onCreate"); | 290 | SingleLockState onCreateState=map.get("onCreate"); | |
| 291 | if (locking(onCreateState)) { | 291 | if (locking(onCreateState)) { | |
| 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 293 | } | 293 | } | |
| 294 | SingleLockState onStartState=map.get("onStart"); | 294 | SingleLockState onStartState=map.get("onStart"); | |
| 295 | if (locking(onStartState)) { | 295 | if (locking(onStartState)) { | |
| 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 297 | } | 297 | } | |
| 298 | SingleLockState onRestartState=map.get("onRestart"); | 298 | SingleLockState onRestartState=map.get("onRestart"); | |
| 299 | if (locking(onRestartState)) { | 299 | if (locking(onRestartState)) { | |
| 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 301 | } | 301 | } | |
| 302 | SingleLockState onPauseState=map.get("onPause"); | 302 | SingleLockState onPauseState=map.get("onPause"); | |
| 303 | if (!unlocking(onPauseState)) { | 303 | if (!unlocking(onPauseState)) { | |
| 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 305 | } | 305 | } | |
| 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | } | 309 | } | |
| 310 | if (component.getComponentType().equals("Service")) { | 310 | if (component.getComponentType().equals("Service")) { | |
| 311 | SingleLockState onStartState=getServiceOnStart(); | 311 | SingleLockState onStartState=getServiceOnStart(); | |
| 312 | SingleLockState onDestroyState=map.get("onDestroy"); | 312 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 315 | } | 315 | } | |
| 316 | if (weakUnlocking(onDestroyState) && !strongUnlocking(state)) { | 316 | if (weakUnlocking(onDestroyState) && !strongUnlocking(onDestroyState)) { | |
| 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 318 | } | 318 | } | |
| 319 | } | 319 | } | |
| 320 | if (component.getComponentType().equals("RunnableThread")) { | 320 | if (component.getComponentType().equals("RunnableThread")) { | |
| 321 | SingleLockState runState=map.get("run"); | 321 | SingleLockState runState=map.get("run"); | |
| 322 | if (locking(runState)) { | 322 | if (locking(runState)) { | |
| 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 324 | } | 324 | } | |
| 325 | } | 325 | } | |
| 326 | if (component.getComponentType().equals("Handler")) { | 326 | if (component.getComponentType().equals("Handler")) { | |
| 327 | SingleLockState handleState=map.get("handleMessage"); | 327 | SingleLockState handleState=map.get("handleMessage"); | |
| 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 330 | } | 330 | } | |
| 331 | } | 331 | } | |
| 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 333 | SingleLockState onReceiveState=map.get("onReceive"); | 333 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 334 | if (locking(onReceiveState)) { | 334 | if (locking(onReceiveState)) { | |
| 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 336 | } | 336 | } | |
| 337 | } | 337 | } | |
| 338 | } | 338 | } | |
| 339 | } | 339 | } | |
| 340 | } | 340 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_074 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_075 | |||
|---|---|---|---|---|
|
340 lines 13667 bytes Last modified : Mon May 14 23:48:12 2012 |
355 lines 13880 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:44.084 | 1 | //Time : 2012-04-26 20:49:49.181 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | 4 | ERROR: Encountered " "void" "void "" at line 309, column 47. | |
| 5 | CHANGE IfStmt to IfStmt = 2 | 5 | Was expecting one of: | |
| 6 | CHANGE MethodDeclaration to MethodDeclaration = 1 | 6 | "false" ... | |
| 7 | changes = 4 | 7 | "new" ... | |
| 8 | changes to method solveFacts = 1 | 8 | "null" ... | |
| 9 | private/protected method declarations = 1 | 9 | "super" ... | |
| 10 | "this" ... | |||
| 11 | "true" ... | |||
| 12 | <LONG_LITERAL> ... | |||
| 13 | <INTEGER_LITERAL> ... | |||
| 14 | <FLOATING_POINT_LITERAL> ... | |||
| 15 | <CHARACTER_LITERAL> ... | |||
| 16 | <STRING_LITERAL> ... | |||
| 17 | <IDENTIFIER> ... | |||
| 18 | "(" ... | |||
| 19 | "!" ... | |||
| 20 | "~" ... | |||
| 21 | <IDENTIFIER> ... | |||
| 22 | "(" ... | |||
| 23 | ||||
| 24 | [Ljava.lang.StackTraceElement;@5893bca2 = 1 | |||
| 10 | */package energy.analysis; | 25 | */package energy.analysis; | |
| 11 | import java.util.ArrayList; | 26 | import java.util.ArrayList; | |
| 12 | import java.util.HashMap; | 27 | import java.util.HashMap; | |
| 13 | import java.util.HashSet; | 28 | import java.util.HashSet; | |
| 14 | import java.util.Iterator; | 29 | import java.util.Iterator; | |
| 15 | import java.util.Map; | 30 | import java.util.Map; | |
| 16 | import java.util.Map.Entry; | 31 | import java.util.Map.Entry; | |
| 17 | import java.util.Set; | 32 | import java.util.Set; | |
| 18 | import com.ibm.wala.ipa.callgraph.CGNode; | 33 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 19 | import com.ibm.wala.util.collections.Pair; | 34 | import com.ibm.wala.util.collections.Pair; | |
| 20 | import energy.analysis.WakeLockManager.WakeLockInstance; | 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 21 | import energy.components.Component; | 36 | import energy.components.Component; | |
| 22 | import energy.components.Component.CallBack; | 37 | import energy.components.Component.CallBack; | |
| 23 | import energy.interproc.CompoundLockState; | 38 | import energy.interproc.CompoundLockState; | |
| 24 | import energy.interproc.SingleLockState; | 39 | import energy.interproc.SingleLockState; | |
| 25 | public class AnalysisResults { | 40 | public class AnalysisResults { | |
| 26 | /** | 41 | /** | |
| 27 | * Main structures that hold the analysis results for every component | 42 | * Main structures that hold the analysis results for every component | |
| 28 | */ | 43 | */ | |
| 29 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 44 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 30 | public class ComponentSummary { | 45 | public class ComponentSummary { | |
| 31 | private Component component; | 46 | private Component component; | |
| 32 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 47 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 33 | private HashMap<CGNode,CompoundLockState> allExitStates; | 48 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 34 | public ComponentSummary( Component c){ | 49 | public ComponentSummary( Component c){ | |
| 35 | this.component=c; | 50 | this.component=c; | |
| 36 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 51 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 37 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 52 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 38 | } | 53 | } | |
| 39 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 54 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 40 | return allExitStates; | 55 | return allExitStates; | |
| 41 | } | 56 | } | |
| 42 | public void registerNodeState( CGNode n, CompoundLockState st){ | 57 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 43 | allExitStates.put(n,st); | 58 | allExitStates.put(n,st); | |
| 44 | } | 59 | } | |
| 45 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 60 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 46 | callBackExitStates.put(cb,st); | 61 | callBackExitStates.put(cb,st); | |
| 47 | } | 62 | } | |
| 48 | public CompoundLockState getStateForMethod( String method){ | 63 | public CompoundLockState getStateForMethod( String method){ | |
| 49 | return allExitStates.get(method); | 64 | return allExitStates.get(method); | |
| 50 | } | 65 | } | |
| 51 | public String toString(){ | 66 | public String toString(){ | |
| 52 | StringBuffer sb=new StringBuffer(); | 67 | StringBuffer sb=new StringBuffer(); | |
| 53 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 68 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 54 | CGNode next=it.next(); | 69 | CGNode next=it.next(); | |
| 55 | String name=next.getMethod().getName().toString(); | 70 | String name=next.getMethod().getName().toString(); | |
| 56 | CompoundLockState stateForMethod=getStateForMethod(name); | 71 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 57 | if (stateForMethod != null) { | 72 | if (stateForMethod != null) { | |
| 58 | sb.append(name + ":\n" + stateForMethod.toString()); | 73 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 59 | } | 74 | } | |
| 60 | } | 75 | } | |
| 61 | HashSet<CallBack> callbacks=component.getCallbacks(); | 76 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 62 | if (callbacks != null) { | 77 | if (callbacks != null) { | |
| 63 | if (callbacks.size() > 0) { | 78 | if (callbacks.size() > 0) { | |
| 64 | sb.append("Callbacks:\n"); | 79 | sb.append("Callbacks:\n"); | |
| 65 | for ( CallBack cb : callbacks) { | 80 | for ( CallBack cb : callbacks) { | |
| 66 | String name=cb.getName(); | 81 | String name=cb.getName(); | |
| 67 | ; | 82 | ; | |
| 68 | CompoundLockState stateForMethod=getStateForMethod(name); | 83 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 69 | if (stateForMethod != null) { | 84 | if (stateForMethod != null) { | |
| 70 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 85 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 71 | } | 86 | } | |
| 72 | } | 87 | } | |
| 73 | } | 88 | } | |
| 74 | } | 89 | } | |
| 75 | return null; | 90 | return null; | |
| 76 | } | 91 | } | |
| 77 | } | 92 | } | |
| 78 | public AnalysisResults(){ | 93 | public AnalysisResults(){ | |
| 79 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 94 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 80 | } | 95 | } | |
| 81 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 96 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 82 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 97 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 83 | public static class Result { | 98 | public static class Result { | |
| 84 | private ResultType resultType; | 99 | private ResultType resultType; | |
| 85 | private String message; | 100 | private String message; | |
| 86 | public ResultType getResultType(){ | 101 | public ResultType getResultType(){ | |
| 87 | return resultType; | 102 | return resultType; | |
| 88 | } | 103 | } | |
| 89 | public String getMessage(){ | 104 | public String getMessage(){ | |
| 90 | return message; | 105 | return message; | |
| 91 | } | 106 | } | |
| 92 | public Result( ResultType rt, String msg){ | 107 | public Result( ResultType rt, String msg){ | |
| 93 | message=msg; | 108 | message=msg; | |
| 94 | resultType=rt; | 109 | resultType=rt; | |
| 95 | } | 110 | } | |
| 96 | public String toString(){ | 111 | public String toString(){ | |
| 97 | return (resultType.name() + " " + message); | 112 | return (resultType.name() + " " + message); | |
| 98 | } | 113 | } | |
| 99 | } | 114 | } | |
| 100 | /** | 115 | /** | |
| 101 | * Invoke this after the component has been analyzed | 116 | * Invoke this after the component has been analyzed | |
| 102 | * @param component | 117 | * @param component | |
| 103 | */ | 118 | */ | |
| 104 | public void createComponentSummary( Component component){ | 119 | public void createComponentSummary( Component component){ | |
| 105 | ComponentSummary componentSummary=new ComponentSummary(component); | 120 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 106 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 121 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 107 | CGNode next=it.next(); | 122 | CGNode next=it.next(); | |
| 108 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 123 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 109 | if (exitState != null) { | 124 | if (exitState != null) { | |
| 110 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 125 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 111 | componentSummary.registerNodeState(next,compoundLockState); | 126 | componentSummary.registerNodeState(next,compoundLockState); | |
| 112 | } | 127 | } | |
| 113 | } | 128 | } | |
| 114 | allStates.add(Pair.make(component,componentSummary)); | 129 | allStates.add(Pair.make(component,componentSummary)); | |
| 115 | } | 130 | } | |
| 116 | private LockUsage getLockUsage( SingleLockState runState){ | 131 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 117 | if (runState != null) { | 132 | if (runState != null) { | |
| 118 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 133 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 119 | return LockUsage.LOCKING; | 134 | return LockUsage.LOCKING; | |
| 120 | } | 135 | } | |
| 121 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 136 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 122 | return LockUsage.EMPTY; | 137 | return LockUsage.EMPTY; | |
| 123 | } | 138 | } | |
| 124 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 139 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 125 | return LockUsage.FULL_UNLOCKING; | 140 | return LockUsage.FULL_UNLOCKING; | |
| 126 | } | 141 | } | |
| 127 | else if (runState.isMaybeReleased()) { | 142 | else if (runState.isMaybeReleased()) { | |
| 128 | return LockUsage.UNLOCKING; | 143 | return LockUsage.UNLOCKING; | |
| 129 | } | 144 | } | |
| 130 | else { | 145 | else { | |
| 131 | return LockUsage.UNKNOWN_STATE; | 146 | return LockUsage.UNKNOWN_STATE; | |
| 132 | } | 147 | } | |
| 133 | } | 148 | } | |
| 134 | else { | 149 | else { | |
| 135 | return LockUsage.EMPTY; | 150 | return LockUsage.EMPTY; | |
| 136 | } | 151 | } | |
| 137 | } | 152 | } | |
| 138 | public ArrayList<Result> processResults(){ | 153 | public ArrayList<Result> processResults(){ | |
| 139 | ArrayList<Result> result=new ArrayList<Result>(); | 154 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 140 | System.out.println("\n=========================================="); | 155 | System.out.println("\n=========================================="); | |
| 141 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 156 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 142 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 157 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 143 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 158 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 144 | Component component=pair.fst; | 159 | Component component=pair.fst; | |
| 145 | ComponentSummary cSummary=pair.snd; | 160 | ComponentSummary cSummary=pair.snd; | |
| 146 | ComponentPolicy policy=new ComponentPolicy(component); | 161 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 147 | StringBuffer sb=new StringBuffer(); | 162 | StringBuffer sb=new StringBuffer(); | |
| 148 | boolean printComponent=false; | 163 | boolean printComponent=false; | |
| 149 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 164 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 150 | CGNode node=e.getKey(); | 165 | CGNode node=e.getKey(); | |
| 151 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 166 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 152 | boolean printMethod=false; | 167 | boolean printMethod=false; | |
| 153 | LockUsage lockUsage=LockUsage.EMPTY; | 168 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 154 | CompoundLockState compLS=e.getValue(); | 169 | CompoundLockState compLS=e.getValue(); | |
| 155 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 170 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 156 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 157 | WakeLockInstance wli=fs.getKey(); | 172 | WakeLockInstance wli=fs.getKey(); | |
| 158 | Set<SingleLockState> sls=fs.getValue(); | 173 | Set<SingleLockState> sls=fs.getValue(); | |
| 159 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 174 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 160 | lockUsage=getLockUsage(sl); | 175 | lockUsage=getLockUsage(sl); | |
| 161 | lockUsages.put(wli,lockUsage); | 176 | lockUsages.put(wli,lockUsage); | |
| 162 | if (lockUsage != LockUsage.EMPTY) { | 177 | if (lockUsage != LockUsage.EMPTY) { | |
| 163 | printMethod=true; | 178 | printMethod=true; | |
| 164 | } | 179 | } | |
| 165 | } | 180 | } | |
| 166 | if (printMethod) { | 181 | if (printMethod) { | |
| 167 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 182 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 168 | printComponent=true; | 183 | printComponent=true; | |
| 169 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 184 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 170 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 185 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 186 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 172 | WakeLockInstance key=fs.getKey(); | 187 | WakeLockInstance key=fs.getKey(); | |
| 173 | Set<SingleLockState> value=fs.getValue(); | 188 | Set<SingleLockState> value=fs.getValue(); | |
| 174 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 189 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 175 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 190 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 176 | } | 191 | } | |
| 177 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 192 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 178 | LockUsage lu=getLockUsage(mergedLS); | 193 | LockUsage lu=getLockUsage(mergedLS); | |
| 179 | if (component.isCallBack(node)) { | 194 | if (component.isCallBack(node)) { | |
| 180 | if (usageMap.containsKey(lu)) { | 195 | if (usageMap.containsKey(lu)) { | |
| 181 | usageMap.get(lu).add(Pair.make(component,node)); | 196 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 182 | } | 197 | } | |
| 183 | else { | 198 | else { | |
| 184 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 199 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 185 | set.add(Pair.make(component,node)); | 200 | set.add(Pair.make(component,node)); | |
| 186 | usageMap.put(lu,set); | 201 | usageMap.put(lu,set); | |
| 187 | } | 202 | } | |
| 188 | policy.addFact(node,mergedLS); | 203 | policy.addFact(node,mergedLS); | |
| 189 | } | 204 | } | |
| 190 | } | 205 | } | |
| 191 | } | 206 | } | |
| 192 | } | 207 | } | |
| 193 | if (printComponent) { | 208 | if (printComponent) { | |
| 194 | System.out.println(component.toString() + "\n" + sb.toString()); | 209 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 195 | policy.solveFacts(); | 210 | policy.solveFacts(); | |
| 196 | componentMap.put(component,policy.getLogger()); | 211 | componentMap.put(component,policy.getLogger()); | |
| 197 | } | 212 | } | |
| 198 | } | 213 | } | |
| 199 | System.out.println("==========================================\n"); | 214 | System.out.println("==========================================\n"); | |
| 200 | for ( LockUsage e : usageMap.keySet()) { | 215 | for ( LockUsage e : usageMap.keySet()) { | |
| 201 | System.out.println(e.toString()); | 216 | System.out.println(e.toString()); | |
| 202 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 217 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 203 | System.out.println(" " + s.toString()); | 218 | System.out.println(" " + s.toString()); | |
| 204 | } | 219 | } | |
| 205 | } | 220 | } | |
| 206 | System.out.println("==========================================\n"); | 221 | System.out.println("==========================================\n"); | |
| 207 | for ( Component e : componentMap.keySet()) { | 222 | for ( Component e : componentMap.keySet()) { | |
| 208 | Logger logger=componentMap.get(e); | 223 | Logger logger=componentMap.get(e); | |
| 209 | if (!logger.isEmpty()) { | 224 | if (!logger.isEmpty()) { | |
| 210 | System.out.println(e.toString()); | 225 | System.out.println(e.toString()); | |
| 211 | System.out.println(logger.toString()); | 226 | System.out.println(logger.toString()); | |
| 212 | System.out.println("\n"); | 227 | System.out.println("\n"); | |
| 213 | } | 228 | } | |
| 214 | result=logger.getStringList(); | 229 | result=logger.getStringList(); | |
| 215 | } | 230 | } | |
| 216 | return result; | 231 | return result; | |
| 217 | } | 232 | } | |
| 218 | public class Logger extends ArrayList<Result> { | 233 | public class Logger extends ArrayList<Result> { | |
| 219 | private static final long serialVersionUID=4402714524487791090L; | 234 | private static final long serialVersionUID=4402714524487791090L; | |
| 220 | public void output(){ | 235 | public void output(){ | |
| 221 | for ( Result r : this) { | 236 | for ( Result r : this) { | |
| 222 | System.out.println(" " + r.getResultType().toString()); | 237 | System.out.println(" " + r.getResultType().toString()); | |
| 223 | } | 238 | } | |
| 224 | } | 239 | } | |
| 225 | public ArrayList<Result> getStringList(){ | 240 | public ArrayList<Result> getStringList(){ | |
| 226 | return this; | 241 | return this; | |
| 227 | } | 242 | } | |
| 228 | public String toString(){ | 243 | public String toString(){ | |
| 229 | StringBuffer result=new StringBuffer(); | 244 | StringBuffer result=new StringBuffer(); | |
| 230 | for ( Result r : this) { | 245 | for ( Result r : this) { | |
| 231 | result.append(r.toString() + "\n"); | 246 | result.append(r.toString() + "\n"); | |
| 232 | } | 247 | } | |
| 233 | return result.toString(); | 248 | return result.toString(); | |
| 234 | } | 249 | } | |
| 235 | } | 250 | } | |
| 236 | public class ComponentPolicy { | 251 | public class ComponentPolicy { | |
| 237 | private Component component; | 252 | private Component component; | |
| 238 | public ComponentPolicy( Component component){ | 253 | public ComponentPolicy( Component component){ | |
| 239 | this.component=component; | 254 | this.component=component; | |
| 240 | map=new HashMap<String,SingleLockState>(); | 255 | map=new HashMap<String,SingleLockState>(); | |
| 241 | logger=new Logger(); | 256 | logger=new Logger(); | |
| 242 | } | 257 | } | |
| 243 | private HashMap<String,SingleLockState> map; | 258 | private HashMap<String,SingleLockState> map; | |
| 244 | public void addFact( CGNode n, SingleLockState st){ | 259 | public void addFact( CGNode n, SingleLockState st){ | |
| 245 | map.put(n.getMethod().getName().toString(),st); | 260 | map.put(n.getMethod().getName().toString(),st); | |
| 246 | } | 261 | } | |
| 247 | private boolean unlocking( SingleLockState state){ | 262 | private boolean unlocking( SingleLockState state){ | |
| 248 | return (strongUnlocking(state) || weakUnlocking(state)); | 263 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 249 | } | 264 | } | |
| 250 | private boolean strongUnlocking( SingleLockState state){ | 265 | private boolean strongUnlocking( SingleLockState state){ | |
| 251 | if (state != null) { | 266 | if (state != null) { | |
| 252 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 267 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 253 | } | 268 | } | |
| 254 | return true; | 269 | return true; | |
| 255 | } | 270 | } | |
| 256 | private boolean weakUnlocking( SingleLockState state){ | 271 | private boolean weakUnlocking( SingleLockState state){ | |
| 257 | if (state != null) { | 272 | if (state != null) { | |
| 258 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 273 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 259 | } | 274 | } | |
| 260 | return true; | 275 | return true; | |
| 261 | } | 276 | } | |
| 262 | private boolean locking( SingleLockState onCreateState){ | 277 | private boolean locking( SingleLockState onCreateState){ | |
| 263 | if (onCreateState != null) { | 278 | if (onCreateState != null) { | |
| 264 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 279 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 265 | } | 280 | } | |
| 266 | return false; | 281 | return false; | |
| 267 | } | 282 | } | |
| 268 | private Logger logger; | 283 | private Logger logger; | |
| 269 | private void logNote( Result result){ | 284 | private void logNote( Result result){ | |
| 270 | logger.add(result); | 285 | logger.add(result); | |
| 271 | } | 286 | } | |
| 272 | public Logger getLogger(){ | 287 | public Logger getLogger(){ | |
| 273 | return logger; | 288 | return logger; | |
| 274 | } | 289 | } | |
| 275 | private SingleLockState getServiceOnStart(){ | 290 | private SingleLockState getServiceOnStart(){ | |
| 276 | SingleLockState onStart=map.get("onStart"); | 291 | SingleLockState onStart=map.get("onStart"); | |
| 277 | SingleLockState onStartCommand=map.get("onStartCommand"); | 292 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 278 | if (onStartCommand == null) { | 293 | if (onStartCommand == null) { | |
| 279 | return onStart; | 294 | return onStart; | |
| 280 | } | 295 | } | |
| 281 | else { | 296 | else { | |
| 282 | return onStartCommand; | 297 | return onStartCommand; | |
| 283 | } | 298 | } | |
| 284 | } | 299 | } | |
| 285 | /** | 300 | /** | |
| 286 | * TODO: make sure the same lock is locked and unlocked... | 301 | * TODO: make sure the same lock is locked and unlocked... | |
| 287 | */ | 302 | */ | |
| 288 | public void solveFacts(){ | 303 | public void solveFacts(){ | |
| 289 | if (component.getComponentType().equals("Activity")) { | 304 | if (component.getComponentType().equals("Activity")) { | |
| 290 | SingleLockState onCreateState=map.get("onCreate"); | 305 | SingleLockState onCreateState=map.get("onCreate"); | |
| 291 | if (locking(onCreateState)) { | 306 | if (locking(onCreateState)) { | |
| 292 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 307 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 293 | } | 308 | } | |
| 294 | SingleLockState onStartState=map.get("onStart"); | 309 | SingleLockState onStartState=map.get("onStart"); | |
| 295 | if (locking(onStartState)) { | 310 | if (locking(onStartState)) { | |
| 296 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 311 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 297 | } | 312 | } | |
| 298 | SingleLockState onRestartState=map.get("onRestart"); | 313 | SingleLockState onRestartState=map.get("onRestart"); | |
| 299 | if (locking(onRestartState)) { | 314 | if (locking(onRestartState)) { | |
| 300 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 315 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 301 | } | 316 | } | |
| 302 | SingleLockState onPauseState=map.get("onPause"); | 317 | SingleLockState onPauseState=map.get("onPause"); | |
| 303 | if (!unlocking(onPauseState)) { | 318 | if (!unlocking(onPauseState)) { | |
| 304 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 319 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 305 | } | 320 | } | |
| 306 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 321 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 307 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 308 | } | 323 | } | |
| 309 | } | 324 | } | |
| 310 | if (component.getComponentType().equals("Service")) { | 325 | if (component.getComponentType().equals("Service")) { | |
| 311 | SingleLockState onStartState=getServiceOnStart(); | 326 | SingleLockState onStartState=getServiceOnStart(); | |
| 312 | SingleLockState onDestroyState=map.get("onDestroy"); | 327 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 313 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 328 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 314 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 329 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 315 | } | 330 | } | |
| 316 | if (weakUnlocking(onDestroyState) && !strongUnlocking(onDestroyState)) { | 331 | if (weakUnlocking(onDestroyState) && (void)!strongUnlocking(onDestroyState)) { | |
| 317 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 332 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 318 | } | 333 | } | |
| 319 | } | 334 | } | |
| 320 | if (component.getComponentType().equals("RunnableThread")) { | 335 | if (component.getComponentType().equals("RunnableThread")) { | |
| 321 | SingleLockState runState=map.get("run"); | 336 | SingleLockState runState=map.get("run"); | |
| 322 | if (locking(runState)) { | 337 | if (locking(runState)) { | |
| 323 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 338 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 324 | } | 339 | } | |
| 325 | } | 340 | } | |
| 326 | if (component.getComponentType().equals("Handler")) { | 341 | if (component.getComponentType().equals("Handler")) { | |
| 327 | SingleLockState handleState=map.get("handleMessage"); | 342 | SingleLockState handleState=map.get("handleMessage"); | |
| 328 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 343 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 329 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 344 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 330 | } | 345 | } | |
| 331 | } | 346 | } | |
| 332 | if (component.getComponentType().equals("BroadcastReceiver")) { | 347 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 333 | SingleLockState onReceiveState=map.get("onReceive"); | 348 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 334 | if (locking(onReceiveState)) { | 349 | if (locking(onReceiveState)) { | |
| 335 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 350 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 336 | } | 351 | } | |
| 337 | } | 352 | } | |
| 338 | } | 353 | } | |
| 339 | } | 354 | } | |
| 340 | } | 355 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_075 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_076 | |||
|---|---|---|---|---|
|
355 lines 13880 bytes Last modified : Mon May 14 23:48:12 2012 |
356 lines 13886 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:49.181 | 1 | //Time : 2012-04-26 20:49:57.004 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | ERROR: Encountered " "void" "void "" at line 309, column 47. | 4 | ERROR: Encountered " "void" "void "" at line 331, column 47. | |
| 5 | Was expecting one of: | 5 | Was expecting one of: | |
| 6 | "false" ... | 6 | "false" ... | |
| 7 | "new" ... | 7 | "new" ... | |
| 8 | "null" ... | 8 | "null" ... | |
| 9 | "super" ... | 9 | "super" ... | |
| 10 | "this" ... | 10 | "this" ... | |
| 11 | "true" ... | 11 | "true" ... | |
| 12 | <LONG_LITERAL> ... | 12 | <LONG_LITERAL> ... | |
| 13 | <INTEGER_LITERAL> ... | 13 | <INTEGER_LITERAL> ... | |
| 14 | <FLOATING_POINT_LITERAL> ... | 14 | <FLOATING_POINT_LITERAL> ... | |
| 15 | <CHARACTER_LITERAL> ... | 15 | <CHARACTER_LITERAL> ... | |
| 16 | <STRING_LITERAL> ... | 16 | <STRING_LITERAL> ... | |
| 17 | <IDENTIFIER> ... | 17 | <IDENTIFIER> ... | |
| 18 | "(" ... | 18 | "(" ... | |
| 19 | "!" ... | 19 | "!" ... | |
| 20 | "~" ... | 20 | "~" ... | |
| 21 | <IDENTIFIER> ... | 21 | <IDENTIFIER> ... | |
| 22 | "(" ... | 22 | "(" ... | |
| 23 | 23 | |||
| 24 | [Ljava.lang.StackTraceElement;@5893bca2 = 1 | 24 | [Ljava.lang.StackTraceElement;@32b3a5a0 = 1 | |
| 25 | */package energy.analysis; | 25 | */package energy.analysis; | |
| 26 | import java.util.ArrayList; | 26 | import java.util.ArrayList; | |
| 27 | import java.util.HashMap; | 27 | import java.util.HashMap; | |
| 28 | import java.util.HashSet; | 28 | import java.util.HashSet; | |
| 29 | import java.util.Iterator; | 29 | import java.util.Iterator; | |
| 30 | import java.util.Map; | 30 | import java.util.Map; | |
| 31 | import java.util.Map.Entry; | 31 | import java.util.Map.Entry; | |
| 32 | import java.util.Set; | 32 | import java.util.Set; | |
| 33 | import com.ibm.wala.ipa.callgraph.CGNode; | 33 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 34 | import com.ibm.wala.util.collections.Pair; | 34 | import com.ibm.wala.util.collections.Pair; | |
| 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 36 | import energy.components.Component; | 36 | import energy.components.Component; | |
| 37 | import energy.components.Component.CallBack; | 37 | import energy.components.Component.CallBack; | |
| 38 | import energy.interproc.CompoundLockState; | 38 | import energy.interproc.CompoundLockState; | |
| 39 | import energy.interproc.SingleLockState; | 39 | import energy.interproc.SingleLockState; | |
| 40 | public class AnalysisResults { | 40 | public class AnalysisResults { | |
| 41 | /** | 41 | /** | |
| 42 | * Main structures that hold the analysis results for every component | 42 | * Main structures that hold the analysis results for every component | |
| 43 | */ | 43 | */ | |
| 44 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 44 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 45 | public class ComponentSummary { | 45 | public class ComponentSummary { | |
| 46 | private Component component; | 46 | private Component component; | |
| 47 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 47 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 48 | private HashMap<CGNode,CompoundLockState> allExitStates; | 48 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 49 | public ComponentSummary( Component c){ | 49 | public ComponentSummary( Component c){ | |
| 50 | this.component=c; | 50 | this.component=c; | |
| 51 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 51 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 52 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 52 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 53 | } | 53 | } | |
| 54 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 54 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 55 | return allExitStates; | 55 | return allExitStates; | |
| 56 | } | 56 | } | |
| 57 | public void registerNodeState( CGNode n, CompoundLockState st){ | 57 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 58 | allExitStates.put(n,st); | 58 | allExitStates.put(n,st); | |
| 59 | } | 59 | } | |
| 60 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 60 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 61 | callBackExitStates.put(cb,st); | 61 | callBackExitStates.put(cb,st); | |
| 62 | } | 62 | } | |
| 63 | public CompoundLockState getStateForMethod( String method){ | 63 | public CompoundLockState getStateForMethod( String method){ | |
| 64 | return allExitStates.get(method); | 64 | return allExitStates.get(method); | |
| 65 | } | 65 | } | |
| 66 | public String toString(){ | 66 | public String toString(){ | |
| 67 | StringBuffer sb=new StringBuffer(); | 67 | StringBuffer sb=new StringBuffer(); | |
| 68 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 68 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 69 | CGNode next=it.next(); | 69 | CGNode next=it.next(); | |
| 70 | String name=next.getMethod().getName().toString(); | 70 | String name=next.getMethod().getName().toString(); | |
| 71 | CompoundLockState stateForMethod=getStateForMethod(name); | 71 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 72 | if (stateForMethod != null) { | 72 | if (stateForMethod != null) { | |
| 73 | sb.append(name + ":\n" + stateForMethod.toString()); | 73 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 74 | } | 74 | } | |
| 75 | } | 75 | } | |
| 76 | HashSet<CallBack> callbacks=component.getCallbacks(); | 76 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 77 | if (callbacks != null) { | 77 | if (callbacks != null) { | |
| 78 | if (callbacks.size() > 0) { | 78 | if (callbacks.size() > 0) { | |
| 79 | sb.append("Callbacks:\n"); | 79 | sb.append("Callbacks:\n"); | |
| 80 | for ( CallBack cb : callbacks) { | 80 | for ( CallBack cb : callbacks) { | |
| 81 | String name=cb.getName(); | 81 | String name=cb.getName(); | |
| 82 | ; | 82 | ; | |
| 83 | CompoundLockState stateForMethod=getStateForMethod(name); | 83 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 84 | if (stateForMethod != null) { | 84 | if (stateForMethod != null) { | |
| 85 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 85 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 86 | } | 86 | } | |
| 87 | } | 87 | } | |
| 88 | } | 88 | } | |
| 89 | } | 89 | } | |
| 90 | return null; | 90 | return null; | |
| 91 | } | 91 | } | |
| 92 | } | 92 | } | |
| 93 | public AnalysisResults(){ | 93 | public AnalysisResults(){ | |
| 94 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 94 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 95 | } | 95 | } | |
| 96 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 96 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 97 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 97 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 98 | public static class Result { | 98 | public static class Result { | |
| 99 | private ResultType resultType; | 99 | private ResultType resultType; | |
| 100 | private String message; | 100 | private String message; | |
| 101 | public ResultType getResultType(){ | 101 | public ResultType getResultType(){ | |
| 102 | return resultType; | 102 | return resultType; | |
| 103 | } | 103 | } | |
| 104 | public String getMessage(){ | 104 | public String getMessage(){ | |
| 105 | return message; | 105 | return message; | |
| 106 | } | 106 | } | |
| 107 | public Result( ResultType rt, String msg){ | 107 | public Result( ResultType rt, String msg){ | |
| 108 | message=msg; | 108 | message=msg; | |
| 109 | resultType=rt; | 109 | resultType=rt; | |
| 110 | } | 110 | } | |
| 111 | public String toString(){ | 111 | public String toString(){ | |
| 112 | return (resultType.name() + " " + message); | 112 | return (resultType.name() + " " + message); | |
| 113 | } | 113 | } | |
| 114 | } | 114 | } | |
| 115 | /** | 115 | /** | |
| 116 | * Invoke this after the component has been analyzed | 116 | * Invoke this after the component has been analyzed | |
| 117 | * @param component | 117 | * @param component | |
| 118 | */ | 118 | */ | |
| 119 | public void createComponentSummary( Component component){ | 119 | public void createComponentSummary( Component component){ | |
| 120 | ComponentSummary componentSummary=new ComponentSummary(component); | 120 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 121 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 121 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 122 | CGNode next=it.next(); | 122 | CGNode next=it.next(); | |
| 123 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 123 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 124 | if (exitState != null) { | 124 | if (exitState != null) { | |
| 125 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 125 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 126 | componentSummary.registerNodeState(next,compoundLockState); | 126 | componentSummary.registerNodeState(next,compoundLockState); | |
| 127 | } | 127 | } | |
| 128 | } | 128 | } | |
| 129 | allStates.add(Pair.make(component,componentSummary)); | 129 | allStates.add(Pair.make(component,componentSummary)); | |
| 130 | } | 130 | } | |
| 131 | private LockUsage getLockUsage( SingleLockState runState){ | 131 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 132 | if (runState != null) { | 132 | if (runState != null) { | |
| 133 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 133 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 134 | return LockUsage.LOCKING; | 134 | return LockUsage.LOCKING; | |
| 135 | } | 135 | } | |
| 136 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 136 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 137 | return LockUsage.EMPTY; | 137 | return LockUsage.EMPTY; | |
| 138 | } | 138 | } | |
| 139 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 139 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 140 | return LockUsage.FULL_UNLOCKING; | 140 | return LockUsage.FULL_UNLOCKING; | |
| 141 | } | 141 | } | |
| 142 | else if (runState.isMaybeReleased()) { | 142 | else if (runState.isMaybeReleased()) { | |
| 143 | return LockUsage.UNLOCKING; | 143 | return LockUsage.UNLOCKING; | |
| 144 | } | 144 | } | |
| 145 | else { | 145 | else { | |
| 146 | return LockUsage.UNKNOWN_STATE; | 146 | return LockUsage.UNKNOWN_STATE; | |
| 147 | } | 147 | } | |
| 148 | } | 148 | } | |
| 149 | else { | 149 | else { | |
| 150 | return LockUsage.EMPTY; | 150 | return LockUsage.EMPTY; | |
| 151 | } | 151 | } | |
| 152 | } | 152 | } | |
| 153 | public ArrayList<Result> processResults(){ | 153 | public ArrayList<Result> processResults(){ | |
| 154 | ArrayList<Result> result=new ArrayList<Result>(); | 154 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 155 | System.out.println("\n=========================================="); | 155 | System.out.println("\n=========================================="); | |
| 156 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 156 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 157 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 157 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 158 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 158 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 159 | Component component=pair.fst; | 159 | Component component=pair.fst; | |
| 160 | ComponentSummary cSummary=pair.snd; | 160 | ComponentSummary cSummary=pair.snd; | |
| 161 | ComponentPolicy policy=new ComponentPolicy(component); | 161 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 162 | StringBuffer sb=new StringBuffer(); | 162 | StringBuffer sb=new StringBuffer(); | |
| 163 | boolean printComponent=false; | 163 | boolean printComponent=false; | |
| 164 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 164 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 165 | CGNode node=e.getKey(); | 165 | CGNode node=e.getKey(); | |
| 166 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 166 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 167 | boolean printMethod=false; | 167 | boolean printMethod=false; | |
| 168 | LockUsage lockUsage=LockUsage.EMPTY; | 168 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 169 | CompoundLockState compLS=e.getValue(); | 169 | CompoundLockState compLS=e.getValue(); | |
| 170 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 170 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 172 | WakeLockInstance wli=fs.getKey(); | 172 | WakeLockInstance wli=fs.getKey(); | |
| 173 | Set<SingleLockState> sls=fs.getValue(); | 173 | Set<SingleLockState> sls=fs.getValue(); | |
| 174 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 174 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 175 | lockUsage=getLockUsage(sl); | 175 | lockUsage=getLockUsage(sl); | |
| 176 | lockUsages.put(wli,lockUsage); | 176 | lockUsages.put(wli,lockUsage); | |
| 177 | if (lockUsage != LockUsage.EMPTY) { | 177 | if (lockUsage != LockUsage.EMPTY) { | |
| 178 | printMethod=true; | 178 | printMethod=true; | |
| 179 | } | 179 | } | |
| 180 | } | 180 | } | |
| 181 | if (printMethod) { | 181 | if (printMethod) { | |
| 182 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 182 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 183 | printComponent=true; | 183 | printComponent=true; | |
| 184 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 184 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 185 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 185 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 186 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 186 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 187 | WakeLockInstance key=fs.getKey(); | 187 | WakeLockInstance key=fs.getKey(); | |
| 188 | Set<SingleLockState> value=fs.getValue(); | 188 | Set<SingleLockState> value=fs.getValue(); | |
| 189 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 189 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 190 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 190 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 191 | } | 191 | } | |
| 192 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 192 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 193 | LockUsage lu=getLockUsage(mergedLS); | 193 | LockUsage lu=getLockUsage(mergedLS); | |
| 194 | if (component.isCallBack(node)) { | 194 | if (component.isCallBack(node)) { | |
| 195 | if (usageMap.containsKey(lu)) { | 195 | if (usageMap.containsKey(lu)) { | |
| 196 | usageMap.get(lu).add(Pair.make(component,node)); | 196 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 197 | } | 197 | } | |
| 198 | else { | 198 | else { | |
| 199 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 199 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 200 | set.add(Pair.make(component,node)); | 200 | set.add(Pair.make(component,node)); | |
| 201 | usageMap.put(lu,set); | 201 | usageMap.put(lu,set); | |
| 202 | } | 202 | } | |
| 203 | policy.addFact(node,mergedLS); | 203 | policy.addFact(node,mergedLS); | |
| 204 | } | 204 | } | |
| 205 | } | 205 | } | |
| 206 | } | 206 | } | |
| 207 | } | 207 | } | |
| 208 | if (printComponent) { | 208 | if (printComponent) { | |
| 209 | System.out.println(component.toString() + "\n" + sb.toString()); | 209 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 210 | policy.solveFacts(); | 210 | policy.solveFacts(); | |
| 211 | componentMap.put(component,policy.getLogger()); | 211 | componentMap.put(component,policy.getLogger()); | |
| 212 | } | 212 | } | |
| 213 | } | 213 | } | |
| 214 | System.out.println("==========================================\n"); | 214 | System.out.println("==========================================\n"); | |
| 215 | for ( LockUsage e : usageMap.keySet()) { | 215 | for ( LockUsage e : usageMap.keySet()) { | |
| 216 | System.out.println(e.toString()); | 216 | System.out.println(e.toString()); | |
| 217 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 217 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 218 | System.out.println(" " + s.toString()); | 218 | System.out.println(" " + s.toString()); | |
| 219 | } | 219 | } | |
| 220 | } | 220 | } | |
| 221 | System.out.println("==========================================\n"); | 221 | System.out.println("==========================================\n"); | |
| 222 | for ( Component e : componentMap.keySet()) { | 222 | for ( Component e : componentMap.keySet()) { | |
| 223 | Logger logger=componentMap.get(e); | 223 | Logger logger=componentMap.get(e); | |
| 224 | if (!logger.isEmpty()) { | 224 | if (!logger.isEmpty()) { | |
| 225 | System.out.println(e.toString()); | 225 | System.out.println(e.toString()); | |
| 226 | System.out.println(logger.toString()); | 226 | System.out.println(logger.toString()); | |
| 227 | System.out.println("\n"); | 227 | System.out.println("\n"); | |
| 228 | } | 228 | } | |
| 229 | result=logger.getStringList(); | 229 | result=logger.getStringList(); | |
| 230 | } | 230 | } | |
| 231 | return result; | 231 | return result; | |
| 232 | } | 232 | } | |
| 233 | public class Logger extends ArrayList<Result> { | 233 | public class Logger extends ArrayList<Result> { | |
| 234 | private static final long serialVersionUID=4402714524487791090L; | 234 | private static final long serialVersionUID=4402714524487791090L; | |
| 235 | public void output(){ | 235 | public void output(){ | |
| 236 | for ( Result r : this) { | 236 | for ( Result r : this) { | |
| 237 | System.out.println(" " + r.getResultType().toString()); | 237 | System.out.println(" " + r.getResultType().toString()); | |
| 238 | } | 238 | } | |
| 239 | } | 239 | } | |
| 240 | public ArrayList<Result> getStringList(){ | 240 | public ArrayList<Result> getStringList(){ | |
| 241 | return this; | 241 | return this; | |
| 242 | } | 242 | } | |
| 243 | public String toString(){ | 243 | public String toString(){ | |
| 244 | StringBuffer result=new StringBuffer(); | 244 | StringBuffer result=new StringBuffer(); | |
| 245 | for ( Result r : this) { | 245 | for ( Result r : this) { | |
| 246 | result.append(r.toString() + "\n"); | 246 | result.append(r.toString() + "\n"); | |
| 247 | } | 247 | } | |
| 248 | return result.toString(); | 248 | return result.toString(); | |
| 249 | } | 249 | } | |
| 250 | } | 250 | } | |
| 251 | public class ComponentPolicy { | 251 | public class ComponentPolicy { | |
| 252 | private Component component; | 252 | private Component component; | |
| 253 | public ComponentPolicy( Component component){ | 253 | public ComponentPolicy( Component component){ | |
| 254 | this.component=component; | 254 | this.component=component; | |
| 255 | map=new HashMap<String,SingleLockState>(); | 255 | map=new HashMap<String,SingleLockState>(); | |
| 256 | logger=new Logger(); | 256 | logger=new Logger(); | |
| 257 | } | 257 | } | |
| 258 | private HashMap<String,SingleLockState> map; | 258 | private HashMap<String,SingleLockState> map; | |
| 259 | public void addFact( CGNode n, SingleLockState st){ | 259 | public void addFact( CGNode n, SingleLockState st){ | |
| 260 | map.put(n.getMethod().getName().toString(),st); | 260 | map.put(n.getMethod().getName().toString(),st); | |
| 261 | } | 261 | } | |
| 262 | private boolean unlocking( SingleLockState state){ | 262 | private boolean unlocking( SingleLockState state){ | |
| 263 | return (strongUnlocking(state) || weakUnlocking(state)); | 263 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 264 | } | 264 | } | |
| 265 | private boolean strongUnlocking( SingleLockState state){ | 265 | private boolean strongUnlocking( SingleLockState state){ | |
| 266 | if (state != null) { | 266 | if (state != null) { | |
| 267 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 267 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 268 | } | 268 | } | |
| 269 | return true; | 269 | return true; | |
| 270 | } | 270 | } | |
| 271 | private boolean weakUnlocking( SingleLockState state){ | 271 | private boolean weakUnlocking( SingleLockState state){ | |
| 272 | if (state != null) { | 272 | if (state != null) { | |
| 273 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 273 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 274 | } | 274 | } | |
| 275 | return true; | 275 | return true; | |
| 276 | } | 276 | } | |
| 277 | private boolean locking( SingleLockState onCreateState){ | 277 | private boolean locking( SingleLockState onCreateState){ | |
| 278 | if (onCreateState != null) { | 278 | if (onCreateState != null) { | |
| 279 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 279 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 280 | } | 280 | } | |
| 281 | return false; | 281 | return false; | |
| 282 | } | 282 | } | |
| 283 | private Logger logger; | 283 | private Logger logger; | |
| 284 | private void logNote( Result result){ | 284 | private void logNote( Result result){ | |
| 285 | logger.add(result); | 285 | logger.add(result); | |
| 286 | } | 286 | } | |
| 287 | public Logger getLogger(){ | 287 | public Logger getLogger(){ | |
| 288 | return logger; | 288 | return logger; | |
| 289 | } | 289 | } | |
| 290 | private SingleLockState getServiceOnStart(){ | 290 | private SingleLockState getServiceOnStart(){ | |
| 291 | SingleLockState onStart=map.get("onStart"); | 291 | SingleLockState onStart=map.get("onStart"); | |
| 292 | SingleLockState onStartCommand=map.get("onStartCommand"); | 292 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 293 | if (onStartCommand == null) { | 293 | if (onStartCommand == null) { | |
| 294 | return onStart; | 294 | return onStart; | |
| 295 | } | 295 | } | |
| 296 | else { | 296 | else { | |
| 297 | return onStartCommand; | 297 | return onStartCommand; | |
| 298 | } | 298 | } | |
| 299 | } | 299 | } | |
| 300 | /** | 300 | /** | |
| 301 | * TODO: make sure the same lock is locked and unlocked... | 301 | * TODO: make sure the same lock is locked and unlocked... | |
| 302 | */ | 302 | */ | |
| 303 | public void solveFacts(){ | 303 | public void solveFacts(){ | |
| 304 | if (component.getComponentType().equals("Activity")) { | 304 | if (component.getComponentType().equals("Activity")) { | |
| 305 | SingleLockState onCreateState=map.get("onCreate"); | 305 | SingleLockState onCreateState=map.get("onCreate"); | |
| 306 | if (locking(onCreateState)) { | 306 | if (locking(onCreateState)) { | |
| 307 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 307 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 308 | } | 308 | } | |
| 309 | SingleLockState onStartState=map.get("onStart"); | 309 | SingleLockState onStartState=map.get("onStart"); | |
| 310 | if (locking(onStartState)) { | 310 | if (locking(onStartState)) { | |
| 311 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 311 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 312 | } | 312 | } | |
| 313 | SingleLockState onRestartState=map.get("onRestart"); | 313 | SingleLockState onRestartState=map.get("onRestart"); | |
| 314 | if (locking(onRestartState)) { | 314 | if (locking(onRestartState)) { | |
| 315 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 315 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 316 | } | 316 | } | |
| 317 | SingleLockState onPauseState=map.get("onPause"); | 317 | SingleLockState onPauseState=map.get("onPause"); | |
| 318 | if (!unlocking(onPauseState)) { | 318 | if (!unlocking(onPauseState)) { | |
| 319 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 319 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 320 | } | 320 | } | |
| 321 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 321 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 322 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 323 | } | 323 | } | |
| 324 | } | 324 | } | |
| 325 | if (component.getComponentType().equals("Service")) { | 325 | if (component.getComponentType().equals("Service")) { | |
| 326 | SingleLockState onStartState=getServiceOnStart(); | 326 | SingleLockState onStartState=getServiceOnStart(); | |
| 327 | SingleLockState onDestroyState=map.get("onDestroy"); | 327 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 328 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 328 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 329 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 329 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 330 | } | 330 | } | |
| 331 | if (weakUnlocking(onDestroyState) && (void)!strongUnlocking(onDestroyState)) { | 331 | if (weakUnlocking(onDestroyState) && (!strongUnlocking(onDestroyState))) ; | |
| 332 | { | |||
| 332 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 333 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 333 | } | 334 | } | |
| 334 | } | 335 | } | |
| 335 | if (component.getComponentType().equals("RunnableThread")) { | 336 | if (component.getComponentType().equals("RunnableThread")) { | |
| 336 | SingleLockState runState=map.get("run"); | 337 | SingleLockState runState=map.get("run"); | |
| 337 | if (locking(runState)) { | 338 | if (locking(runState)) { | |
| 338 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 339 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 339 | } | 340 | } | |
| 340 | } | 341 | } | |
| 341 | if (component.getComponentType().equals("Handler")) { | 342 | if (component.getComponentType().equals("Handler")) { | |
| 342 | SingleLockState handleState=map.get("handleMessage"); | 343 | SingleLockState handleState=map.get("handleMessage"); | |
| 343 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 344 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 344 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 345 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 345 | } | 346 | } | |
| 346 | } | 347 | } | |
| 347 | if (component.getComponentType().equals("BroadcastReceiver")) { | 348 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 348 | SingleLockState onReceiveState=map.get("onReceive"); | 349 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 349 | if (locking(onReceiveState)) { | 350 | if (locking(onReceiveState)) { | |
| 350 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 351 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 351 | } | 352 | } | |
| 352 | } | 353 | } | |
| 353 | } | 354 | } | |
| 354 | } | 355 | } | |
| 355 | } | 356 | } |
|
Generated by diff2html © Yves Bailly, MandrakeSoft S.A. 2001 diff2html is licensed under the GNU GPL. |
| DiffViewer/output/AnalysisResults.java//AnalysisResults.java_076 | DiffViewer/output/AnalysisResults.java//AnalysisResults.java_077 | |||
|---|---|---|---|---|
|
356 lines 13886 bytes Last modified : Mon May 14 23:48:12 2012 |
341 lines 13709 bytes Last modified : Mon May 14 23:48:12 2012 |
|||
| 1 | //Time : 2012-04-26 20:49:57.004 | 1 | //Time : 2012-04-26 20:49:58.294 | |
| 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | 2 | //Files Open : /pvekris/src/main/java/energy/analysis/AnalysisResults.java /pvekris/src/main/java/energy/analysis/Opts.java /pvekris/src/main/java/energy/analysis/ComponentManager.java /mcmutton/src/main/java/edu/ucsd/salud/mcmutton/BugHunt.java | |
| 3 | /*AST Changes : | 3 | /*AST Changes : | |
| 4 | ERROR: Encountered " "void" "void "" at line 331, column 47. | 4 | CHANGE ClassOrInterfaceDeclaration to ClassOrInterfaceDeclaration = 1 | |
| 5 | Was expecting one of: | 5 | CHANGE IfStmt to IfStmt = 1 | |
| 6 | "false" ... | 6 | CHANGE IfStmt to IfStmt BlockStmt = 1 | |
| 7 | "new" ... | 7 | CHANGE MethodDeclaration to MethodDeclaration = 1 | |
| 8 | "null" ... | 8 | changes = 4 | |
| 9 | "super" ... | 9 | changes to method solveFacts = 1 | |
| 10 | "this" ... | 10 | private/protected method declarations = 1 | |
| 11 | "true" ... | |||
| 12 | <LONG_LITERAL> ... | |||
| 13 | <INTEGER_LITERAL> ... | |||
| 14 | <FLOATING_POINT_LITERAL> ... | |||
| 15 | <CHARACTER_LITERAL> ... | |||
| 16 | <STRING_LITERAL> ... | |||
| 17 | <IDENTIFIER> ... | |||
| 18 | "(" ... | |||
| 19 | "!" ... | |||
| 20 | "~" ... | |||
| 21 | <IDENTIFIER> ... | |||
| 22 | "(" ... | |||
| 23 | ||||
| 24 | [Ljava.lang.StackTraceElement;@32b3a5a0 = 1 | |||
| 25 | */package energy.analysis; | 11 | */package energy.analysis; | |
| 26 | import java.util.ArrayList; | 12 | import java.util.ArrayList; | |
| 27 | import java.util.HashMap; | 13 | import java.util.HashMap; | |
| 28 | import java.util.HashSet; | 14 | import java.util.HashSet; | |
| 29 | import java.util.Iterator; | 15 | import java.util.Iterator; | |
| 30 | import java.util.Map; | 16 | import java.util.Map; | |
| 31 | import java.util.Map.Entry; | 17 | import java.util.Map.Entry; | |
| 32 | import java.util.Set; | 18 | import java.util.Set; | |
| 33 | import com.ibm.wala.ipa.callgraph.CGNode; | 19 | import com.ibm.wala.ipa.callgraph.CGNode; | |
| 34 | import com.ibm.wala.util.collections.Pair; | 20 | import com.ibm.wala.util.collections.Pair; | |
| 35 | import energy.analysis.WakeLockManager.WakeLockInstance; | 21 | import energy.analysis.WakeLockManager.WakeLockInstance; | |
| 36 | import energy.components.Component; | 22 | import energy.components.Component; | |
| 37 | import energy.components.Component.CallBack; | 23 | import energy.components.Component.CallBack; | |
| 38 | import energy.interproc.CompoundLockState; | 24 | import energy.interproc.CompoundLockState; | |
| 39 | import energy.interproc.SingleLockState; | 25 | import energy.interproc.SingleLockState; | |
| 40 | public class AnalysisResults { | 26 | public class AnalysisResults { | |
| 41 | /** | 27 | /** | |
| 42 | * Main structures that hold the analysis results for every component | 28 | * Main structures that hold the analysis results for every component | |
| 43 | */ | 29 | */ | |
| 44 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | 30 | private HashSet<Pair<Component,ComponentSummary>> allStates=null; | |
| 45 | public class ComponentSummary { | 31 | public class ComponentSummary { | |
| 46 | private Component component; | 32 | private Component component; | |
| 47 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | 33 | private HashMap<CallBack,CompoundLockState> callBackExitStates; | |
| 48 | private HashMap<CGNode,CompoundLockState> allExitStates; | 34 | private HashMap<CGNode,CompoundLockState> allExitStates; | |
| 49 | public ComponentSummary( Component c){ | 35 | public ComponentSummary( Component c){ | |
| 50 | this.component=c; | 36 | this.component=c; | |
| 51 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | 37 | allExitStates=new HashMap<CGNode,CompoundLockState>(); | |
| 52 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | 38 | callBackExitStates=new HashMap<Component.CallBack,CompoundLockState>(); | |
| 53 | } | 39 | } | |
| 54 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | 40 | public HashMap<CGNode,CompoundLockState> getAllExitStates(){ | |
| 55 | return allExitStates; | 41 | return allExitStates; | |
| 56 | } | 42 | } | |
| 57 | public void registerNodeState( CGNode n, CompoundLockState st){ | 43 | public void registerNodeState( CGNode n, CompoundLockState st){ | |
| 58 | allExitStates.put(n,st); | 44 | allExitStates.put(n,st); | |
| 59 | } | 45 | } | |
| 60 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | 46 | public void registerCallBackState( CallBack cb, CompoundLockState st){ | |
| 61 | callBackExitStates.put(cb,st); | 47 | callBackExitStates.put(cb,st); | |
| 62 | } | 48 | } | |
| 63 | public CompoundLockState getStateForMethod( String method){ | 49 | public CompoundLockState getStateForMethod( String method){ | |
| 64 | return allExitStates.get(method); | 50 | return allExitStates.get(method); | |
| 65 | } | 51 | } | |
| 66 | public String toString(){ | 52 | public String toString(){ | |
| 67 | StringBuffer sb=new StringBuffer(); | 53 | StringBuffer sb=new StringBuffer(); | |
| 68 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 54 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 69 | CGNode next=it.next(); | 55 | CGNode next=it.next(); | |
| 70 | String name=next.getMethod().getName().toString(); | 56 | String name=next.getMethod().getName().toString(); | |
| 71 | CompoundLockState stateForMethod=getStateForMethod(name); | 57 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 72 | if (stateForMethod != null) { | 58 | if (stateForMethod != null) { | |
| 73 | sb.append(name + ":\n" + stateForMethod.toString()); | 59 | sb.append(name + ":\n" + stateForMethod.toString()); | |
| 74 | } | 60 | } | |
| 75 | } | 61 | } | |
| 76 | HashSet<CallBack> callbacks=component.getCallbacks(); | 62 | HashSet<CallBack> callbacks=component.getCallbacks(); | |
| 77 | if (callbacks != null) { | 63 | if (callbacks != null) { | |
| 78 | if (callbacks.size() > 0) { | 64 | if (callbacks.size() > 0) { | |
| 79 | sb.append("Callbacks:\n"); | 65 | sb.append("Callbacks:\n"); | |
| 80 | for ( CallBack cb : callbacks) { | 66 | for ( CallBack cb : callbacks) { | |
| 81 | String name=cb.getName(); | 67 | String name=cb.getName(); | |
| 82 | ; | 68 | ; | |
| 83 | CompoundLockState stateForMethod=getStateForMethod(name); | 69 | CompoundLockState stateForMethod=getStateForMethod(name); | |
| 84 | if (stateForMethod != null) { | 70 | if (stateForMethod != null) { | |
| 85 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | 71 | sb.append(" " + name + ":\n"+ stateForMethod.toString()); | |
| 86 | } | 72 | } | |
| 87 | } | 73 | } | |
| 88 | } | 74 | } | |
| 89 | } | 75 | } | |
| 90 | return null; | 76 | return null; | |
| 91 | } | 77 | } | |
| 92 | } | 78 | } | |
| 93 | public AnalysisResults(){ | 79 | public AnalysisResults(){ | |
| 94 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | 80 | allStates=new HashSet<Pair<Component,ComponentSummary>>(); | |
| 95 | } | 81 | } | |
| 96 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | 82 | public enum LockUsage { LOCKING, UNLOCKING, NOLOCKING, LOCKUNLOCK, EMPTY, UNKNOWN_STATE, FULL_UNLOCKING} | |
| 97 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | 83 | public enum ResultType { UNRESOLVED_INTERESTING_CALLBACKS, LOCKING_ON_CREATE, START_DESTROY, SERVICE_DESTROY, THREAD_RUN, HANDLE_MESSAGE, BROADCAST_RECEIVER_ONRECEIVE, LOCKING_ON_START, LOCKING_ON_RESTART, STRONG_PAUSE_RESUME, WEAK_PAUSE_RESUME, WEAK_SERVICE_DESTROY, STRONG_SERVICE_DESTROY, DID_NOT_PROCESS, OPTIMIZATION_FAILURE, ANALYSIS_FAILURE, UNIMPLEMENTED_FAILURE} | |
| 98 | public static class Result { | 84 | public static class Result { | |
| 99 | private ResultType resultType; | 85 | private ResultType resultType; | |
| 100 | private String message; | 86 | private String message; | |
| 101 | public ResultType getResultType(){ | 87 | public ResultType getResultType(){ | |
| 102 | return resultType; | 88 | return resultType; | |
| 103 | } | 89 | } | |
| 104 | public String getMessage(){ | 90 | public String getMessage(){ | |
| 105 | return message; | 91 | return message; | |
| 106 | } | 92 | } | |
| 107 | public Result( ResultType rt, String msg){ | 93 | public Result( ResultType rt, String msg){ | |
| 108 | message=msg; | 94 | message=msg; | |
| 109 | resultType=rt; | 95 | resultType=rt; | |
| 110 | } | 96 | } | |
| 111 | public String toString(){ | 97 | public String toString(){ | |
| 112 | return (resultType.name() + " " + message); | 98 | return (resultType.name() + " " + message); | |
| 113 | } | 99 | } | |
| 114 | } | 100 | } | |
| 115 | /** | 101 | /** | |
| 116 | * Invoke this after the component has been analyzed | 102 | * Invoke this after the component has been analyzed | |
| 117 | * @param component | 103 | * @param component | |
| 118 | */ | 104 | */ | |
| 119 | public void createComponentSummary( Component component){ | 105 | public void createComponentSummary( Component component){ | |
| 120 | ComponentSummary componentSummary=new ComponentSummary(component); | 106 | ComponentSummary componentSummary=new ComponentSummary(component); | |
| 121 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | 107 | for (Iterator<CGNode> it=component.getCallgraph().iterator(); it.hasNext(); ) { | |
| 122 | CGNode next=it.next(); | 108 | CGNode next=it.next(); | |
| 123 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | 109 | Map<WakeLockInstance,Set<SingleLockState>> exitState=component.getExitState(next); | |
| 124 | if (exitState != null) { | 110 | if (exitState != null) { | |
| 125 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | 111 | CompoundLockState compoundLockState=new CompoundLockState(exitState); | |
| 126 | componentSummary.registerNodeState(next,compoundLockState); | 112 | componentSummary.registerNodeState(next,compoundLockState); | |
| 127 | } | 113 | } | |
| 128 | } | 114 | } | |
| 129 | allStates.add(Pair.make(component,componentSummary)); | 115 | allStates.add(Pair.make(component,componentSummary)); | |
| 130 | } | 116 | } | |
| 131 | private LockUsage getLockUsage( SingleLockState runState){ | 117 | private LockUsage getLockUsage( SingleLockState runState){ | |
| 132 | if (runState != null) { | 118 | if (runState != null) { | |
| 133 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | 119 | if (runState.isMaybeAcquired() && (!runState.isMaybeReleased())) { | |
| 134 | return LockUsage.LOCKING; | 120 | return LockUsage.LOCKING; | |
| 135 | } | 121 | } | |
| 136 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 122 | else if (!runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 137 | return LockUsage.EMPTY; | 123 | return LockUsage.EMPTY; | |
| 138 | } | 124 | } | |
| 139 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | 125 | else if (runState.isMaybeReleased() && (!runState.isMaybeAcquired())) { | |
| 140 | return LockUsage.FULL_UNLOCKING; | 126 | return LockUsage.FULL_UNLOCKING; | |
| 141 | } | 127 | } | |
| 142 | else if (runState.isMaybeReleased()) { | 128 | else if (runState.isMaybeReleased()) { | |
| 143 | return LockUsage.UNLOCKING; | 129 | return LockUsage.UNLOCKING; | |
| 144 | } | 130 | } | |
| 145 | else { | 131 | else { | |
| 146 | return LockUsage.UNKNOWN_STATE; | 132 | return LockUsage.UNKNOWN_STATE; | |
| 147 | } | 133 | } | |
| 148 | } | 134 | } | |
| 149 | else { | 135 | else { | |
| 150 | return LockUsage.EMPTY; | 136 | return LockUsage.EMPTY; | |
| 151 | } | 137 | } | |
| 152 | } | 138 | } | |
| 153 | public ArrayList<Result> processResults(){ | 139 | public ArrayList<Result> processResults(){ | |
| 154 | ArrayList<Result> result=new ArrayList<Result>(); | 140 | ArrayList<Result> result=new ArrayList<Result>(); | |
| 155 | System.out.println("\n=========================================="); | 141 | System.out.println("\n=========================================="); | |
| 156 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | 142 | HashMap<LockUsage,Set<Pair<Component,CGNode>>> usageMap=new HashMap<LockUsage,Set<Pair<Component,CGNode>>>(); | |
| 157 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | 143 | HashMap<Component,Logger> componentMap=new HashMap<Component,Logger>(); | |
| 158 | for ( Pair<Component,ComponentSummary> pair : allStates) { | 144 | for ( Pair<Component,ComponentSummary> pair : allStates) { | |
| 159 | Component component=pair.fst; | 145 | Component component=pair.fst; | |
| 160 | ComponentSummary cSummary=pair.snd; | 146 | ComponentSummary cSummary=pair.snd; | |
| 161 | ComponentPolicy policy=new ComponentPolicy(component); | 147 | ComponentPolicy policy=new ComponentPolicy(component); | |
| 162 | StringBuffer sb=new StringBuffer(); | 148 | StringBuffer sb=new StringBuffer(); | |
| 163 | boolean printComponent=false; | 149 | boolean printComponent=false; | |
| 164 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | 150 | for ( Entry<CGNode,CompoundLockState> e : cSummary.getAllExitStates().entrySet()) { | |
| 165 | CGNode node=e.getKey(); | 151 | CGNode node=e.getKey(); | |
| 166 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | 152 | HashMap<WakeLockInstance,LockUsage> lockUsages=new HashMap<WakeLockInstance,LockUsage>(); | |
| 167 | boolean printMethod=false; | 153 | boolean printMethod=false; | |
| 168 | LockUsage lockUsage=LockUsage.EMPTY; | 154 | LockUsage lockUsage=LockUsage.EMPTY; | |
| 169 | CompoundLockState compLS=e.getValue(); | 155 | CompoundLockState compLS=e.getValue(); | |
| 170 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | 156 | Map<WakeLockInstance,Set<SingleLockState>> allLockStates=compLS.getAllLockStates(); | |
| 171 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | 157 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : allLockStates.entrySet()) { | |
| 172 | WakeLockInstance wli=fs.getKey(); | 158 | WakeLockInstance wli=fs.getKey(); | |
| 173 | Set<SingleLockState> sls=fs.getValue(); | 159 | Set<SingleLockState> sls=fs.getValue(); | |
| 174 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | 160 | SingleLockState sl=SingleLockState.mergeSingleLockStates(sls); | |
| 175 | lockUsage=getLockUsage(sl); | 161 | lockUsage=getLockUsage(sl); | |
| 176 | lockUsages.put(wli,lockUsage); | 162 | lockUsages.put(wli,lockUsage); | |
| 177 | if (lockUsage != LockUsage.EMPTY) { | 163 | if (lockUsage != LockUsage.EMPTY) { | |
| 178 | printMethod=true; | 164 | printMethod=true; | |
| 179 | } | 165 | } | |
| 180 | } | 166 | } | |
| 181 | if (printMethod) { | 167 | if (printMethod) { | |
| 182 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | 168 | if (Opts.OUTPUT_ALL_NODE_INFO || component.isCallBack(node)) { | |
| 183 | printComponent=true; | 169 | printComponent=true; | |
| 184 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | 170 | HashSet<SingleLockState> tempState=new HashSet<SingleLockState>(); | |
| 185 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | 171 | sb.append(" " + node.getMethod().getSignature().toString() + "\n"); | |
| 186 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | 172 | for ( Entry<WakeLockInstance,Set<SingleLockState>> fs : compLS.getAllLockStates().entrySet()) { | |
| 187 | WakeLockInstance key=fs.getKey(); | 173 | WakeLockInstance key=fs.getKey(); | |
| 188 | Set<SingleLockState> value=fs.getValue(); | 174 | Set<SingleLockState> value=fs.getValue(); | |
| 189 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | 175 | tempState.add(SingleLockState.mergeSingleLockStates(value)); | |
| 190 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | 176 | sb.append("\t" + key.toString() + "\n\t"+ value.toString()+ "\n"); | |
| 191 | } | 177 | } | |
| 192 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | 178 | SingleLockState mergedLS=SingleLockState.mergeSingleLockStates(tempState); | |
| 193 | LockUsage lu=getLockUsage(mergedLS); | 179 | LockUsage lu=getLockUsage(mergedLS); | |
| 194 | if (component.isCallBack(node)) { | 180 | if (component.isCallBack(node)) { | |
| 195 | if (usageMap.containsKey(lu)) { | 181 | if (usageMap.containsKey(lu)) { | |
| 196 | usageMap.get(lu).add(Pair.make(component,node)); | 182 | usageMap.get(lu).add(Pair.make(component,node)); | |
| 197 | } | 183 | } | |
| 198 | else { | 184 | else { | |
| 199 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | 185 | HashSet<Pair<Component,CGNode>> set=new HashSet<Pair<Component,CGNode>>(); | |
| 200 | set.add(Pair.make(component,node)); | 186 | set.add(Pair.make(component,node)); | |
| 201 | usageMap.put(lu,set); | 187 | usageMap.put(lu,set); | |
| 202 | } | 188 | } | |
| 203 | policy.addFact(node,mergedLS); | 189 | policy.addFact(node,mergedLS); | |
| 204 | } | 190 | } | |
| 205 | } | 191 | } | |
| 206 | } | 192 | } | |
| 207 | } | 193 | } | |
| 208 | if (printComponent) { | 194 | if (printComponent) { | |
| 209 | System.out.println(component.toString() + "\n" + sb.toString()); | 195 | System.out.println(component.toString() + "\n" + sb.toString()); | |
| 210 | policy.solveFacts(); | 196 | policy.solveFacts(); | |
| 211 | componentMap.put(component,policy.getLogger()); | 197 | componentMap.put(component,policy.getLogger()); | |
| 212 | } | 198 | } | |
| 213 | } | 199 | } | |
| 214 | System.out.println("==========================================\n"); | 200 | System.out.println("==========================================\n"); | |
| 215 | for ( LockUsage e : usageMap.keySet()) { | 201 | for ( LockUsage e : usageMap.keySet()) { | |
| 216 | System.out.println(e.toString()); | 202 | System.out.println(e.toString()); | |
| 217 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | 203 | for ( Pair<Component,CGNode> s : usageMap.get(e)) { | |
| 218 | System.out.println(" " + s.toString()); | 204 | System.out.println(" " + s.toString()); | |
| 219 | } | 205 | } | |
| 220 | } | 206 | } | |
| 221 | System.out.println("==========================================\n"); | 207 | System.out.println("==========================================\n"); | |
| 222 | for ( Component e : componentMap.keySet()) { | 208 | for ( Component e : componentMap.keySet()) { | |
| 223 | Logger logger=componentMap.get(e); | 209 | Logger logger=componentMap.get(e); | |
| 224 | if (!logger.isEmpty()) { | 210 | if (!logger.isEmpty()) { | |
| 225 | System.out.println(e.toString()); | 211 | System.out.println(e.toString()); | |
| 226 | System.out.println(logger.toString()); | 212 | System.out.println(logger.toString()); | |
| 227 | System.out.println("\n"); | 213 | System.out.println("\n"); | |
| 228 | } | 214 | } | |
| 229 | result=logger.getStringList(); | 215 | result=logger.getStringList(); | |
| 230 | } | 216 | } | |
| 231 | return result; | 217 | return result; | |
| 232 | } | 218 | } | |
| 233 | public class Logger extends ArrayList<Result> { | 219 | public class Logger extends ArrayList<Result> { | |
| 234 | private static final long serialVersionUID=4402714524487791090L; | 220 | private static final long serialVersionUID=4402714524487791090L; | |
| 235 | public void output(){ | 221 | public void output(){ | |
| 236 | for ( Result r : this) { | 222 | for ( Result r : this) { | |
| 237 | System.out.println(" " + r.getResultType().toString()); | 223 | System.out.println(" " + r.getResultType().toString()); | |
| 238 | } | 224 | } | |
| 239 | } | 225 | } | |
| 240 | public ArrayList<Result> getStringList(){ | 226 | public ArrayList<Result> getStringList(){ | |
| 241 | return this; | 227 | return this; | |
| 242 | } | 228 | } | |
| 243 | public String toString(){ | 229 | public String toString(){ | |
| 244 | StringBuffer result=new StringBuffer(); | 230 | StringBuffer result=new StringBuffer(); | |
| 245 | for ( Result r : this) { | 231 | for ( Result r : this) { | |
| 246 | result.append(r.toString() + "\n"); | 232 | result.append(r.toString() + "\n"); | |
| 247 | } | 233 | } | |
| 248 | return result.toString(); | 234 | return result.toString(); | |
| 249 | } | 235 | } | |
| 250 | } | 236 | } | |
| 251 | public class ComponentPolicy { | 237 | public class ComponentPolicy { | |
| 252 | private Component component; | 238 | private Component component; | |
| 253 | public ComponentPolicy( Component component){ | 239 | public ComponentPolicy( Component component){ | |
| 254 | this.component=component; | 240 | this.component=component; | |
| 255 | map=new HashMap<String,SingleLockState>(); | 241 | map=new HashMap<String,SingleLockState>(); | |
| 256 | logger=new Logger(); | 242 | logger=new Logger(); | |
| 257 | } | 243 | } | |
| 258 | private HashMap<String,SingleLockState> map; | 244 | private HashMap<String,SingleLockState> map; | |
| 259 | public void addFact( CGNode n, SingleLockState st){ | 245 | public void addFact( CGNode n, SingleLockState st){ | |
| 260 | map.put(n.getMethod().getName().toString(),st); | 246 | map.put(n.getMethod().getName().toString(),st); | |
| 261 | } | 247 | } | |
| 262 | private boolean unlocking( SingleLockState state){ | 248 | private boolean unlocking( SingleLockState state){ | |
| 263 | return (strongUnlocking(state) || weakUnlocking(state)); | 249 | return (strongUnlocking(state) || weakUnlocking(state)); | |
| 264 | } | 250 | } | |
| 265 | private boolean strongUnlocking( SingleLockState state){ | 251 | private boolean strongUnlocking( SingleLockState state){ | |
| 266 | if (state != null) { | 252 | if (state != null) { | |
| 267 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | 253 | return (getLockUsage(state).equals(LockUsage.FULL_UNLOCKING)); | |
| 268 | } | 254 | } | |
| 269 | return true; | 255 | return true; | |
| 270 | } | 256 | } | |
| 271 | private boolean weakUnlocking( SingleLockState state){ | 257 | private boolean weakUnlocking( SingleLockState state){ | |
| 272 | if (state != null) { | 258 | if (state != null) { | |
| 273 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | 259 | return (getLockUsage(state).equals(LockUsage.UNLOCKING)); | |
| 274 | } | 260 | } | |
| 275 | return true; | 261 | return true; | |
| 276 | } | 262 | } | |
| 277 | private boolean locking( SingleLockState onCreateState){ | 263 | private boolean locking( SingleLockState onCreateState){ | |
| 278 | if (onCreateState != null) { | 264 | if (onCreateState != null) { | |
| 279 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | 265 | return (getLockUsage(onCreateState).equals(LockUsage.LOCKING)); | |
| 280 | } | 266 | } | |
| 281 | return false; | 267 | return false; | |
| 282 | } | 268 | } | |
| 283 | private Logger logger; | 269 | private Logger logger; | |
| 284 | private void logNote( Result result){ | 270 | private void logNote( Result result){ | |
| 285 | logger.add(result); | 271 | logger.add(result); | |
| 286 | } | 272 | } | |
| 287 | public Logger getLogger(){ | 273 | public Logger getLogger(){ | |
| 288 | return logger; | 274 | return logger; | |
| 289 | } | 275 | } | |
| 290 | private SingleLockState getServiceOnStart(){ | 276 | private SingleLockState getServiceOnStart(){ | |
| 291 | SingleLockState onStart=map.get("onStart"); | 277 | SingleLockState onStart=map.get("onStart"); | |
| 292 | SingleLockState onStartCommand=map.get("onStartCommand"); | 278 | SingleLockState onStartCommand=map.get("onStartCommand"); | |
| 293 | if (onStartCommand == null) { | 279 | if (onStartCommand == null) { | |
| 294 | return onStart; | 280 | return onStart; | |
| 295 | } | 281 | } | |
| 296 | else { | 282 | else { | |
| 297 | return onStartCommand; | 283 | return onStartCommand; | |
| 298 | } | 284 | } | |
| 299 | } | 285 | } | |
| 300 | /** | 286 | /** | |
| 301 | * TODO: make sure the same lock is locked and unlocked... | 287 | * TODO: make sure the same lock is locked and unlocked... | |
| 302 | */ | 288 | */ | |
| 303 | public void solveFacts(){ | 289 | public void solveFacts(){ | |
| 304 | if (component.getComponentType().equals("Activity")) { | 290 | if (component.getComponentType().equals("Activity")) { | |
| 305 | SingleLockState onCreateState=map.get("onCreate"); | 291 | SingleLockState onCreateState=map.get("onCreate"); | |
| 306 | if (locking(onCreateState)) { | 292 | if (locking(onCreateState)) { | |
| 307 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | 293 | logNote(new Result(ResultType.LOCKING_ON_CREATE,component.toString())); | |
| 308 | } | 294 | } | |
| 309 | SingleLockState onStartState=map.get("onStart"); | 295 | SingleLockState onStartState=map.get("onStart"); | |
| 310 | if (locking(onStartState)) { | 296 | if (locking(onStartState)) { | |
| 311 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | 297 | logNote(new Result(ResultType.LOCKING_ON_START,component.toString())); | |
| 312 | } | 298 | } | |
| 313 | SingleLockState onRestartState=map.get("onRestart"); | 299 | SingleLockState onRestartState=map.get("onRestart"); | |
| 314 | if (locking(onRestartState)) { | 300 | if (locking(onRestartState)) { | |
| 315 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | 301 | logNote(new Result(ResultType.LOCKING_ON_RESTART,component.toString())); | |
| 316 | } | 302 | } | |
| 317 | SingleLockState onPauseState=map.get("onPause"); | 303 | SingleLockState onPauseState=map.get("onPause"); | |
| 318 | if (!unlocking(onPauseState)) { | 304 | if (!unlocking(onPauseState)) { | |
| 319 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | 305 | logNote(new Result(ResultType.STRONG_PAUSE_RESUME,component.toString())); | |
| 320 | } | 306 | } | |
| 321 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | 307 | if (weakUnlocking(onPauseState) && (!strongUnlocking(onPauseState))) { | |
| 322 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | 308 | logNote(new Result(ResultType.WEAK_PAUSE_RESUME,component.toString())); | |
| 323 | } | 309 | } | |
| 324 | } | 310 | } | |
| 325 | if (component.getComponentType().equals("Service")) { | 311 | if (component.getComponentType().equals("Service")) { | |
| 326 | SingleLockState onStartState=getServiceOnStart(); | 312 | SingleLockState onStartState=getServiceOnStart(); | |
| 327 | SingleLockState onDestroyState=map.get("onDestroy"); | 313 | SingleLockState onDestroyState=map.get("onDestroy"); | |
| 328 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | 314 | if (locking(onStartState) && (!unlocking(onDestroyState))) { | |
| 329 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | 315 | logNote(new Result(ResultType.STRONG_SERVICE_DESTROY,component.toString())); | |
| 330 | } | 316 | } | |
| 331 | if (weakUnlocking(onDestroyState) && (!strongUnlocking(onDestroyState))) ; | 317 | if (weakUnlocking(onDestroyState) && (!strongUnlocking(onDestroyState))) { | |
| 332 | { | |||
| 333 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 318 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 334 | } | 319 | } | |
| 335 | } | 320 | } | |
| 336 | if (component.getComponentType().equals("RunnableThread")) { | 321 | if (component.getComponentType().equals("RunnableThread")) { | |
| 337 | SingleLockState runState=map.get("run"); | 322 | SingleLockState runState=map.get("run"); | |
| 338 | if (locking(runState)) { | 323 | if (locking(runState)) { | |
| 339 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | 324 | logNote(new Result(ResultType.THREAD_RUN,component.toString())); | |
| 340 | } | 325 | } | |
| 341 | } | 326 | } | |
| 342 | if (component.getComponentType().equals("Handler")) { | 327 | if (component.getComponentType().equals("Handler")) { | |
| 343 | SingleLockState handleState=map.get("handleMessage"); | 328 | SingleLockState handleState=map.get("handleMessage"); | |
| 344 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | 329 | if (unlocking(handleState) && (!strongUnlocking(handleState))) { | |
| 345 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | 330 | logNote(new Result(ResultType.WEAK_SERVICE_DESTROY,component.toString())); | |
| 346 | } | 331 | } | |
| 347 | } | 332 | } | |
| 348 | if (component.getComponentType().equals("BroadcastReceiver")) { | 333 | if (component.getComponentType().equals("BroadcastReceiver")) { | |
| 349 | SingleLockState onReceiveState=map.get("onReceive"); | 334 | SingleLockState onReceiveState=map.get("onReceive"); | |
| 350 | if (locking(onReceiveState)) { | 335 | if (locking(onReceiveState)) { | |
| 351 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | 336 | logNote(new Result(ResultType.BROADCAST_RECEIVER_ONRECEIVE,component.toString())); | |
| 352 | } | 337 | } | |
| 353 | } | 338 | } | |
| 354 | } | 339 | } | |
| 355 | } | 340 | } | |
| 356 | } | 341 | } |

